<script setup>
import { onMounted, onUnmounted, ref, reactive } from 'vue'
import { OilApp1 } from "./webGLCom1.js";
import { addLoading, removeLoading } from "../threeRender/utils/loading";
import * as THREE from 'three'
import { outlineObj } from "../threeRender/base/composer"
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import TWEEN, { add } from 'three/examples/jsm/libs/tween.module.js';

// 加上“？raw”让vue识别成以字符串导入即可
import DepthVertexShader from './shader/depth_vertex.glsl?raw';
import DepthFragmentShader from './shader/depth_fragment.glsl?raw';
import PickVertexShader from './shader/pick_vertex.glsl?raw';
import PickFragmentShader from './shader/pick_fragment.glsl?raw';
import MaskVertex from './shader/mask_vertex.glsl?raw';
import MaskFragment from './shader/mask_fragment.glsl?raw';
import EdgeVertex from './shader/edge_vertex.glsl?raw';
import EdgeFragment from './shader/edge_fragment.glsl?raw';

//FXAA抗锯齿Shader
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
import { createMultiMaterialObject } from 'three/examples/jsm/utils/SceneUtils.js';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry' ;

// 创建一个Oil网格可视化App实例
let oilMeshViewApp1 = null
let dom = null
let canvas = null

let renderer  = null
let scene  = null
let camera = null


let selectedMenu = ref(0);
let modelSubSectioning = ref(0);
let modelChange = ref(0);
let modelColorChange = ref(0);

let modelsExploderStatus = ref(0);

let btnDisabled = ref(false)

let optNum = ref(10)

const clickFun = (num)=>{
    selectFun(num)
    if(num==0){
        initTween(0,3000,6000)
    }else if(num==2){
        modelSubSectioning.value = 1;
        modelColorChange.value = 0;
    }else if(num==3){
        if(modelsExploderStatus.value==0){
            modelsExploderStatus.value = 1;
            onChangeModelView(2)
        }else{
            modelsExploderStatus.value = 0;
            onChangeModelView(1);
        }
    }else if(num==4){
        modelColorChange.value = 1;
        modelSubSectioning.value = 0;
        setTimeout(()=>{
            colorPreview = document.getElementById('colorPreview');

            hueSlider = document.getElementById('hueSlider');
            saturationSlider = document.getElementById('saturationSlider');
            lightnessSlider = document.getElementById('lightnessSlider');
            opacitySlider = document.getElementById('opacitySlider');

            // Event listeners for sliders
            hueSlider.addEventListener('input', updateColor);
            saturationSlider.addEventListener('input', updateColor);
            lightnessSlider.addEventListener('input', updateColor);
            opacitySlider.addEventListener('input', updateColor);

            // Initialize color
            updateColor();
        },1)
        
    }else if(num==5){
        modelChange.value = 1;
    }else if(num==6){
        if(glassMaterial){
            glassMaterial.wireframe = !glassMaterial.wireframe;
        }
    }
}

const selectFun = (num)=>{
    if(num == selectedMenu.value){
        return
    } else {
        selectedMenu.value = num
    }
}

const changeOilMeshColor = (color="0xc1c1c1", opacity=0.9)=>{
    if(glassMaterial){
        glassMaterial.color = new THREE.Color(parseInt(color));
        glassMaterial.opacity = opacity;

    }
}

function closeModelCut(){
    modelSubSectioning.value = 0;
}

function closeModelColorChange(){
    modelColorChange.value = 0;
}

function closeModelChange(){
    modelChange.value = 0;
}

// Plane作为元素创建数组，Plane的方向法向量、位置根据需要随意定义
let planeArr =  ref([
    //创建一个垂直x轴的平面，方向沿着x轴负方向，沿着x轴正方向平移300,
    new THREE.Plane(new THREE.Vector3(-1, 0, 0), 8000),
    // 垂直y轴的平面
    new THREE.Plane(new THREE.Vector3(0, -1, 0), 2000),
    // 垂直z轴的平面
    new THREE.Plane(new THREE.Vector3(0, 0, -1), 8000)
]);

  function inputFunc1(){
    //planeArr[0].constant
  }
  function inputFunc2(){
    //planeArr[1].constant
  }
  function inputFunc3(){
    //planeArr[2].constant
  }

  function subCut() {   //模型剖切
  }

let colorPreview = null;
let hueSlider = null;
let saturationSlider = null;
let lightnessSlider = null;
let opacitySlider = null;

const hue = ref(0);
const saturation = ref(0);
const lightness = ref(0);
const opacity = ref(0);

function updateColor() {
    hue.value = hueSlider.value;// 色调
    saturation.value = saturationSlider.value;// 饱和度
    lightness.value = lightnessSlider.value;// 亮度
    opacity.value = Number(opacitySlider.value)/100;//透明度
    const hslColor = `hsl(${hue.value}, ${saturation.value}%, ${lightness.value}%)`;
    // hsl转16进制配色
    const hexColor = hslToHex(hue.value, saturation.value, lightness.value);
    setTimeout(()=>{
        colorPreview.style.backgroundColor = hslColor;
        // 输出十六进制颜色值，例如 0x007700
        changeOilMeshColor(hexColor, opacity.value);
    },1)
    //console.log(hslColor, hexColor)
}

function hslToHex(h, s, l) {
  l /= 100;
  const a = s * Math.min(l, 1 - l) / 100;
  const f = n => {
    const k = (n + h / 30) % 12;
    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
    return Math.round(255 * color).toString(16).padStart(2, '0'); // 转换为十六进制并补零
  };
  return parseInt(`0x${f(0)}${f(8)}${f(4)}`, 16);
}


const createCanvas = () => {
    const canvas = document.createElement('canvas');
    canvas.width= window.innerWidth;//画布宽度px
    canvas.height= window.innerHeight;//画布高度px
    //canvas.style.background='black';
    return canvas;
}

const properties = {
    radiusTop: {
      name: 'radiusTop',
      value: 10,
      min: -40,
      max: 40,
      step: 1
    },
    radiusBottom: {
      name: 'radiusBottom',
      value: 5,
      min: -40,
      max: 40,
      step: 1
    },
    height: {
      name: 'height',
      value: 1500,
      min: 0,
      max: 1000,
      step: 1
    },
    segmentsX: {
      name: 'segmentsX',
      value: 8,
      min: 0,
      max: 40,
      step: 1
    },
    segmentsY: {
      name: 'segmentsY',
      value: 8,
      min: 0,
      max: 40,
      step: 1
    },
    openEnded: false
};

const colorsPaletteArrObj = [
    {color:'#ff0f00', name:'1100'},
    {color:'#ff7d00', name:'1000'},
    {color:'#ffec00', name:'900'},
    {color:'#a3ff00', name:'800'},
    {color:'#00ff39', name:'700'},
    {color:'#00ffa8', name:'600'},
    {color:'#00e7ff', name:'500'},
    {color:'#0078ff', name:'300'},
    {color:'#000aff', name:'100'},
]

// 井筒 WELL 数据 使用大地坐标时，XCOORD、YCOORD的值非常大
// 基准点坐标, 分别为XCOORD0和YCOORD0，XCOORD和YCOORD数组只记录偏移量。
// 基准XCOORD0 + 偏移XCOORD
// 基准YCOORD0 + 偏移YCOORD
const XCOORD0 = 630752.507
const YCOORD0 = 4338916.207 
const infoTIME = ref(30)

const coord = {
    XCOORD0: 630752.507,
    YCOORD0: 4338916.207
}

const objectMesh = reactive({name:""})

/*
WELL 1 'GR1-1' 305 'SHUT'
WELL 2 'GR1-2' 370 'LRAT:999.9999 SM3/DAY'
WELL 3 'GR1-3' 370 'LRAT:999.9999 SM3/DAY'
WELL 4 'GR1-4' 371 'LRAT:999.9928 SM3/DAY'
WELL 5 'GR2-2' 355 'SHUT'
WELL 6 'GR2-3' 356 'LRAT:1000 SM3/DAY'
WELL 7 'GR2-4' 331 'LRAT:1000 SM3/DAY'
WELL 8 'GR2-5' 343 'LRAT:1000 SM3/DAY'
WELL 9 'GR3-2' 389 'LRAT:999.9997 SM3/DAY'
WELL 10 'GR3-3' 363 'SHUT'
WELL 11 'GR3-4' 365 'LRAT:1000 SM3/DAY'
WELL 12 'GR3-6' 363 'LRAT:1000 SM3/DAY'
WELL 13 'GR4-1' 370 'LRAT:999.9999 SM3/DAY'
WELL 14 'GR4-2' 347 'SHUT'
WELL 15 'GR4-3' 319 'LRAT:1000 SM3/DAY'
WELL 16 'GR4-4' 355 'LRAT:1000 SM3/DAY'
WELL 17 'GR4-5' 351 'LRAT:1000 SM3/DAY'
WELL 18 'GR4-6' 332 'LRAT:1000 SM3/DAY'
WELL 19 'GR5-1' 382 'LRAT:1000 SM3/DAY'
WELL 20 'GR5-2' 386 'LRAT:1000 SM3/DAY'
WELL 21 'GR5-5' 318 'SHUT'
WELL 22 'GR5-6' 392 'LRAT:1000 SM3/DAY'
WELL 23 'GR6-2' 357 'LRAT:1000 SM3/DAY'
WELL 24 'GR6-3' 312 'SHUT'
WELL 25 'GR6-4' 316 'LRAT:1000 SM3/DAY'
WELL 26 'GR6-5' 351 'LRAT:1000 SM3/DAY'
WELL 27 'GR7-2' 273 'SHUT'
WELL 28 'GR7-3' 195 'LRAT:999.9997 SM3/DAY'
*/

let wellInfo = ref(null);

wellInfo.value = [
    {
        id: '1',//井号
        name: 'GR1-1',//井名
        num: '305',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest 
                rest: [
                    {key:'XCOORD',unit:'m',value: '1634.44'},
                    {key:'YCOORD',unit:'m',value: '-513.6248'},
                    {key:'DEPTH',unit:'m',value: '1852.081'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径 渗透率单位是长度的平方，即与面积的单位相同。但我们称之为达西（D）,常用的单位为毫达西（md）。
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '2',//井号
        name: 'GR1-2',//井名
        num: '370',//井节点数目
        cpr:'LRAT:999.9999 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '1578.101'},
                    {key:'YCOORD',unit:'m',value: '-904.3235'},
                    {key:'DEPTH',unit:'m',value: '1857.264'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '3',//井号
        name: 'GR1-3',//井名
        num: '370',//井节点数目
        cpr:'LRAT:999.9999 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2040.376'},
                    {key:'YCOORD',unit:'m',value: '-613.6444'},
                    {key:'DEPTH',unit:'m',value: '1884.242'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '4',//井号
        name: 'GR1-4',//井名
        num: '371',//井节点数目
        cpr:'LRAT:999.9928 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '1266.302'},
                    {key:'YCOORD',unit:'m',value: '-702.4572'},
                    {key:'DEPTH',unit:'m',value: '1832.496'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '5',//井号
        name: 'GR2-2',//井名
        num: '355',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2321.342'},
                    {key:'YCOORD',unit:'m',value: '-1500.041'},
                    {key:'DEPTH',unit:'m',value: '1884.405'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '6',//井号
        name: 'GR2-3',//井名
        num: '356',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2435.878'},
                    {key:'YCOORD',unit:'m',value: '-1829.453'},
                    {key:'DEPTH',unit:'m',value: '1880.274'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '7',//井号
        name: 'GR2-4',//井名
        num: '331',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2541.56'},
                    {key:'YCOORD',unit:'m',value: '-941.6433'},
                    {key:'DEPTH',unit:'m',value: '1887.254'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '8',//井号
        name: 'GR2-5',//井名
        num: '356',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
                // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2726.393'},
                    {key:'YCOORD',unit:'m',value: '-1284.873'},
                    {key:'DEPTH',unit:'m',value: '1900.401'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]
            }
        ]
        
    },
    {
        id: '9',//井号
        name: 'GR3-2',//井名
        num: '389',//井节点数目
        cpr:'LRAT:999.9997 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '2769.661'},
                    {key:'YCOORD',unit:'m',value: '-1242.292'},
                    {key:'DEPTH',unit:'m',value: '1901.514'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '10',//井号
        name: 'GR3-3',//井名
        num: '363',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3255.522'},
                    {key:'YCOORD',unit:'m',value: '-1449.746'},
                    {key:'DEPTH',unit:'m',value: '1889.97'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '11',//井号
        name: 'GR3-4',//井名
        num: '365',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3354.514'},
                    {key:'YCOORD',unit:'m',value: '-551.0424'},
                    {key:'DEPTH',unit:'m',value: '1929.548'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '12',//井号
        name: 'GR3-6',//井名
        num: '363',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
                // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3671.499'},
                    {key:'YCOORD',unit:'m',value: '-1282.311'},
                    {key:'DEPTH',unit:'m',value: '1925.202'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]
            }
        ]
        
    },
    {
        id: '13',//井号
        name: 'GR4-1',//井名
        num: '370',//井节点数目
        cpr:'LRAT:999.9999 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3755.437'},
                    {key:'YCOORD',unit:'m',value: '-344.6722'},
                    {key:'DEPTH',unit:'m',value: '1960.381'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '14',//井号
        name: 'GR4-2',//井名
        num: '347',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3925.16'},
                    {key:'YCOORD',unit:'m',value: '-686.4225'},
                    {key:'DEPTH',unit:'m',value: '1963.771'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '15',//井号
        name: 'GR4-3',//井名
        num: '319',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4098.873'},
                    {key:'YCOORD',unit:'m',value: '-1049.915'},
                    {key:'DEPTH',unit:'m',value: '1950.633'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '16',//井号
        name: 'GR4-4',//井名
        num: '355',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
                // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4092.854'},
                    {key:'YCOORD',unit:'m',value: '-166.9816'},
                    {key:'DEPTH',unit:'m',value: '1984.752'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]
            }
        ]
        
    },
    {
        id: '17',//井号
        name: 'GR4-5',//井名
        num: '351',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4245.787'},
                    {key:'YCOORD',unit:'m',value: '-516.7445'},
                    {key:'DEPTH',unit:'m',value: '1989.236'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '18',//井号
        name: 'GR4-6',//井名
        num: '332',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4504.464'},
                    {key:'YCOORD',unit:'m',value: '-870.1137'},
                    {key:'DEPTH',unit:'m',value: '1981.408'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '19',//井号
        name: 'GR5-1',//井名
        num: '382',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
                // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3889.889'},
                    {key:'YCOORD',unit:'m',value: '-1840.704'},
                    {key:'DEPTH',unit:'m',value: '1912.83'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]
            }
        ]
        
    },
    {
        id: '20',//井号
        name: 'GR5-2',//井名
        num: '386',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '3932.508'},
                    {key:'YCOORD',unit:'m',value: '-2208.018'},
                    {key:'DEPTH',unit:'m',value: '1909.972'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '21',//井号
        name: 'GR5-5',//井名
        num: '318',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4372.747'},
                    {key:'YCOORD',unit:'m',value: '-1994.812'},
                    {key:'DEPTH',unit:'m',value: '1920.678'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '22',//井号
        name: 'GR5-6',//井名
        num: '392',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4591.463'},
                    {key:'YCOORD',unit:'m',value: '-2394.178'},
                    {key:'DEPTH',unit:'m',value: '1920.089'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '23',//井号
        name: 'GR6-2',//井名
        num: '357',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4804.098'},
                    {key:'YCOORD',unit:'m',value: '-267.5754'},
                    {key:'DEPTH',unit:'m',value: '2016.597'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '24',//井号
        name: 'GR6-3',//井名
        num: '312',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '4987.155'},
                    {key:'YCOORD',unit:'m',value: '-626.5946'},
                    {key:'DEPTH',unit:'m',value: '2020.773'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '25',//井号
        name: 'GR6-4',//井名
        num: '316',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '5130.427'},
                    {key:'YCOORD',unit:'m',value: '-123.4141'},
                    {key:'DEPTH',unit:'m',value: '2015.812'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '26',//井号
        name: 'GR6-5',//井名
        num: '351',//井节点数目
        cpr:'LRAT:1000 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
              // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '5601.456'},
                    {key:'YCOORD',unit:'m',value: '-789.9283'},
                    {key:'DEPTH',unit:'m',value: '2018.281'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]  
            }
        ]
        
    },
    {
        id: '27',//井号
        name: 'GR7-2',//井名
        num: '273',//井节点数目
        cpr:'SHUT',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
               // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '5770.853'},
                    {key:'YCOORD',unit:'m',value: '-271.2598'},
                    {key:'DEPTH',unit:'m',value: '2032.128'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ] 
            }
        ]
        
    },
    {
        id: '28',//井号
        name: 'GR7-3',//井名
        num: '195',//井节点数目
        cpr:'LRAT:999.9997 SM3/DAY',//当前生产制度
        time: '0',//数据时间
        showStatus: false,
        data:[
            {
                // 静态数据 rest
                rest: [
                    {key:'XCOORD',unit:'m',value: '5941.789'},
                    {key:'YCOORD',unit:'m',value: '285.394'},
                    {key:'DEPTH',unit:'m',value: '1992.729'},
                    {key:'STAGE',unit:'integer',value: '0'},
                    {key:'OUTLET',unit:'integer',value: '-1'},
                ],
                //动态数据 motion
                motion: [
                    {key:'WI',unit:'mD*m',value: '0'},//井筒内径
                    {key:'PRES',unit:'bar',value: '186.7146'},//压力
                    {key:'PCON',unit:'',value: '0'},//油
                    {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                    {key:'QO',unit:'m3/day',value: '0'},//油oil
                    {key:'QG',unit:'m3/day',value: '0'},//气gas
                    {key:'QW',unit:'m3/day',value: '0'},//水water
                    {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                    {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                    {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
                ]
            }
        ]
    }
]


let downProgress = null
let model = null
let modelItems = new THREE.Group()
const  url = import.meta.env.BASE_URL + 'public/models/draco/gltf/' + '1b-s-data3-1-0Draco.glb'

const modelList = ref([url]);
for(let i = 1; i< 558;i++){
    if(!(i%1)){
        modelList.value.push(import.meta.env.BASE_URL + "public/models/draco/glb/draco/"+"data3-1-"+i+"Draco.glb");
        //modelList.value.push(import.meta.env.BASE_URL + "public/models/draco/glb/origi/"+"data3-1-"+i+".glb");
        //addOilMesh(import.meta.env.BASE_URL + "public/models/draco/glb/draco/"+"data3-1-"+i+"Draco.glb");
    }
}
// 纹理加载器管理
const manager = new THREE.LoadingManager()
manager.onLoad = ()=>{
    console.log( 'Loading complete!')
    modelItems.add(model)

    setTimeout(() => {
        btnDisabled.value = false
        removeLoading()
        /*AnimCam.animateCamera(camera, 
            controls, 
            { x: camera.position.x, y: camera.position.y, z: camera.position.z }, 
            { x: 3, y: 3, z: 3 }, 
        300, () => {})*/

        //initTween( camera.position.x+1, camera.position.y+1, camera.position.z+1 )

    }, 1500);
}

manager.onProgress =  async ( url, itemsLoaded, itemsTotal )=> {
    //console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' )
    downProgress = itemsLoaded / itemsTotal === 1 ? '100%' : `${((itemsLoaded / itemsTotal) * 100).toFixed(0)}` + '%'
    //instance.proxy.$forceUpdate();
    console.log("progress: ", downProgress)
}
manager.onError = ( url )=> {
    console.log( 'There was an error loading ' + url )
}
// 添加通过gltf-pipeline可以大幅度压缩gltf/glb模型文件。将 glTF 转换为 glb（和反向）
//将缓冲区/纹理保存为嵌入或单独的文件
//将 glTF 1.0 模型转换为 glTF 2.0（使用KHR_techniques_webgl和KHR_blend扩展）

//draco_decoder.js— Emscripten 编译的解码器，与任何现代浏览器兼容。
//draco_decoder.wasm— WebAssembly 解码器，与较新的浏览器和设备兼容。
//draco_wasm_wrapper.js— WASM 解码器的 JavaScript 包装器。

//应用Draco解压/压缩网格
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath(import.meta.env.BASE_URL + 'public/draco/')
// 创建GLTF加载器对象
const gltfLoader = new GLTFLoader(manager)
gltfLoader.setDRACOLoader(dracoLoader)

const colorList = [
    //卡其色
    '0xb69860',
    //浅黄
    '0xedd3a1',
    //枯色
    '0xe0c38c',
    //榛色
    '0xbfa46f',
    //樺茶色
    '0x726250',
    //朽葉色
    '0x917347',
    //路考茶
    '0x8c7042',
    //国防色
    '0x7b6c3e',
    //利休茶
    '0xa59564',
    //空五倍子色
    '0x9d896c',
    //生壁色
    '0x94846a',
    //肥後煤竹
    '0x897858',
    //媚茶
    '0x716246',
    //黄唐色
    '0xb98c46',
    //桑染
    '0xb79b5b',
    //黄橡
    '0xb68d4c',
    //芝翫茶
    '0xad7e4e',
    //狐色
    '0xc38743',
    //黄土色
    '0xc39143',
    //香染
    '0xad7d4c',
    //枇杷茶
    '0xae7c4f'
]

const colorsPalette = [
    {color:'0xff0f00', name:'1100'},
    {color:'0xff7d00', name:'1000'},
    {color:'0xffec00', name:'900'},
    {color:'0xa3ff00', name:'800'},
    {color:'0x00ff39', name:'700'},
    {color:'0x00ffa8', name:'600'},
    {color:'0x00e7ff', name:'500'},
    {color:'0x0078ff', name:'300'},
    {color:'0x000aff', name:'100'},
]


let glassMaterial = null
const matParams = {
    vertexColors: true,//使用顶点颜色渲染
    //color: color,
    //color: new THREE.Color(parseInt(colorList[0])),
    // 渲染两面
    side: THREE.DoubleSide,
    wireframe: false, //材质的网格wireframe属性
    clearcoat: 1.0,//物体表面清漆层或者说透明涂层的厚度
    clearcoatRoughness: 0.1,//透明涂层表面的粗糙度
    transmission: 0.5,//物理材质透光率,模拟玻璃、半透明塑料一类的视觉效果,代替普通透明属性.opacity 设置Mesh透明度,即便完全透射的情况下仍可保持高反射率。
    ior: 1.5,//折射率.ior非金属材料的折射率从1.0到2.333。默认值为1.5。
    metalness: 0.9,//金属度
    roughness: 0.5,//粗糙度
    bumpScale: 0.5, // 凹凸贴图的高度
    envMapIntensity: 2.5, //环境贴图对Mesh表面影响程度
    opacity: 0.9,
    // 我们同样需要把tansparent属性打开
    transparent: true,
    // 设置材质的剪裁平面的属性 将剪裁平面应用到材质上
    clippingPlanes: planeArr.value, // 将剪裁平面应用到材质上,初始化剪裁平面数组
    //改变剪裁方式，剪裁所有平面要剪裁部分的交集
    clipIntersection: true,
    clipShadows: true // 允许剪裁影响阴影
}

//MeshLambertMaterial
glassMaterial = new THREE.MeshPhysicalMaterial(matParams);

//井筒静态、动态数据
const wstuOut = import.meta.env.BASE_URL + "public/models/JD_Refined_BO3_wstu.out.txt"
let xhr="";//声明变量容纳XMLHttpRequest对象
let textArr = [];
let wellData = new Map();
let timeTemp = ""
let wellId = ""
let wellProp = ""
//封装XMLHttpRequest对象创建方法（用于兼容低版本IE浏览器）
function createXHR(){
    if(new window.XMLHttpRequest){//如果浏览器支持对象XMLHttpRequest
        xhr=new XMLHttpRequest();
    }else{
        xhr=new ActiveXObject("Microsoft.XMLH");//低版本IE使用ActiveXObject
    }
}

function setDataProp(item,index){
    if(wellData.has(timeTemp)){
        let temp = wellData.get(timeTemp)
        if(temp.data.hasOwnProperty(wellId)){
            // 修改元素
            let tem = temp.data[wellId]
            tem[item] = {unit: textArr[index+1],data: []}
            wellProp = item
            temp.data[wellId] = tem
            wellData.set(timeTemp, temp);
        }
    }
}

function getWstuOutData(){
    
    createXHR();//调用函数以创建XMLHttpRequest对象

    //使用XMLHttpRequest对象发送请求
    xhr.open("get",wstuOut,false);//创建请求
    xhr.send(null);//发送请求

    //获取返回的json数据，
    let personStr=xhr.responseText;//返回的数据都是字符串，不具备对象方法
    let textLen = personStr.length;
    
    let str = ""
    for(let i = 0; i< textLen-1;i++){
        let s = personStr.substring(i,i+1);
        if(s != ' ' && s != '\n' ){
            str += s;
        }else{
            if(str!=""){
                textArr.push(str);
                str = "";
            }
        }
    }
    //console.log(textArr)
    
    textArr.map((item,index)=>{
        if(item=="XCOORD0"){
                // 使用正则表达式替换所有的 \r
                let newStr = textArr[index+1].replace(/\r/g, '');
                // 使用 set 方法添加元素
                wellData.set('XCOORD0', newStr);
                //console.log(textArr[index+1])
        }else if(item =="YCOORD0"){
                // 使用正则表达式替换所有的 \r
                let newStr = textArr[index+1].replace(/\r/g, '');
                // 使用 set 方法添加元素
                wellData.set('YCOORD0', newStr);
                //console.log(textArr[index+1])
        }else if(item == "Time"){
                // 使用正则表达式替换所有的 \r
                let newStr = textArr[index+1].replace(/\r/g, '');
                timeTemp = newStr
                wellData.set(newStr, { time: newStr, data:[] });
                //console.log(textArr[index+1])
        }else if(item == "WELL"){
                // 修改元素
                let temp = wellData.get(timeTemp)
                wellId = textArr[index+1]
                let id = textArr[index+1]
                let name = textArr[index+2]
                let num = textArr[index+3]
                let spr = ""
                if(textArr[index+4].replace(/\r/g, '') == "'SHUT'"){
                    spr = textArr[index+4].replace(/\r/g, '')
                }else{
                    spr = textArr[index+4]+textArr[index+5].replace(/\r/g, '')
                }
                temp.data[wellId] = { id: id, name: name, num: num, spr: spr}
                wellData.set(timeTemp, temp);
                //console.log(textArr[index+1],textArr[index+2],textArr[index+3],textArr[index+4],textArr[index+5])
        }else if(item == "WI"){
                // 检查键是否存在 对应id油井
                // 修改元素
                setDataProp(item,index)
            //console.log(textArr[index+1])
        }else if(item == "PRES"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "PCON"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "VM"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "QO"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "QW"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "WH"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "QWI"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "XCOORD"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "YCOORD"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "DEPTH"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "STAGE"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item == "OUTLET"){
            // 检查键是否存在 对应id油井
            setDataProp(item,index)
                //console.log(textArr[index+1])
        }else if(item.includes("\r")&&item!="\r"){
                //console.log(textArr[index])
                if(timeTemp!=""&&wellId!=""&&wellProp!=""){
                    if(wellData.has(timeTemp)){
                        let temp = wellData.get(timeTemp)
                        if(temp.data.hasOwnProperty(wellId)){
                            // 修改元素
                            let tem = temp.data[wellId]
                            if(tem[wellProp]&& tem[wellProp].hasOwnProperty('data')){
                                //console.log(tem[wellProp],wellId,wellProp,item)
                                // 使用正则表达式替换所有的 \r
                                let newStr = item.replace(/\r/g, '');
                                tem[wellProp].data.push(newStr)

                                temp.data[wellId] = tem
                                wellData.set(timeTemp, temp);
                            }
                        }
                    }
                }
                if(textArr[index+1]!=undefined&&textArr[index+1]!="\r"){
                    //console.log(textArr[index+1])
                }
        }else if(timeTemp!=""&&wellId!=""&&wellProp!=""){
                if(wellData.has(timeTemp)){
                    let temp = wellData.get(timeTemp)
                    if(temp.data.hasOwnProperty(wellId)){
                        // 修改元素
                        let tem = temp.data[wellId]
                        if(tem[wellProp]&& tem[wellProp].hasOwnProperty('data')){
                            //console.log(tem[wellProp],wellId,wellProp,item)
                            if(tem[wellProp].unit!=item){
                                tem[wellProp].data.push(item)
                                temp.data[wellId] = tem
                                wellData.set(timeTemp, temp);
                            }
                        }
                    }
                }
        }
    })

}

function getWellTimePropValue(time="0", id=1, prop="XCOORD"){
    // 遍历 Map 时间time 0的1号油井油井数据
    let temp = wellData.get(time)
    let temData = null
    if(temp.hasOwnProperty("data")){
        temp.data.map((item,index)=>{
            if(item.id==id){
                //console.log(prop,item[prop].data)
                if(item.hasOwnProperty(prop) && item[prop].hasOwnProperty("data")){
                    temData=item[prop].data
                }
            }
        })
    }
    //const isEmpty = Object.getOwnPropertyNames(temData).length === 0
    //if(!isEmpty){
    if(temData!=null){
        return temData
    }
}

let wellObj = {
    id: '1',//井号
    name: 'GR1-1',//井名
    num: '305',//井节点数目
    cpr:'SHUT',//当前生产制度
    time: '0',//数据时间
    showStatus: false,
    data:[
        {
            // 静态数据 rest 
            rest: [
                {key:'XCOORD',unit:'m',value: '1634.44'},
                {key:'YCOORD',unit:'m',value: '-513.6248'},
                {key:'DEPTH',unit:'m',value: '1852.081'},
                {key:'STAGE',unit:'integer',value: '0'},
                {key:'OUTLET',unit:'integer',value: '-1'},
            ],
            //动态数据 motion
            motion: [
                {key:'WI',unit:'mD*m',value: '0'},//井筒内径 渗透率单位是长度的平方，即与面积的单位相同。但我们称之为达西（D）,常用的单位为毫达西（md）。
                {key:'PRES',unit:'bar',value: '186.7146'},//压力
                {key:'PCON',unit:'',value: '0'},//油
                {key:'VM',unit:'m/day',value: '61038.07'},//井筒流速
                {key:'QO',unit:'m3/day',value: '0'},//油oil
                {key:'QG',unit:'m3/day',value: '0'},//气gas
                {key:'QW',unit:'m3/day',value: '0'},//水water
                {key:'WH',unit:'Frac',value: '0.5771189'},//持水率water
                {key:'GH',unit:'Frac',value: '0.0064207'},//持气率gas
                {key:'RS',unit:'Mscf/ST3',value: '1.36927'},//溶解气油比率
            ]  
        }
    ]
}

function addWellTube(id=1){
    //getWellTimePropValue("0",1,"YCOORD")
    let XCOORD = getWellTimePropValue("0",id,"XCOORD")
    //console.log(XCOORD)
    let YCOORD = getWellTimePropValue("0",id,"YCOORD")
    //console.log(YCOORD)
    let DEPTH = getWellTimePropValue("0",id,"DEPTH")
    //console.log(DEPTH)
    //let WI = getWellTimePropValue("0",id,"WI")
    //console.log(WI)

    let xyzCoord = [
        //new THREE.Vector3(0, 0, 0),
        //new THREE.Vector3(0, 1500, 0),
        //new THREE.Vector3(1000, 1000, 0),
        //new THREE.Vector3(0, 1800, 1000),
        //new THREE.Vector3(1000, 1000, 1000)
    ]
    
    let x = 0, y = 0, z = 0;

    for(let i = 0; i< XCOORD.length;i++){
        // 位置矫正 补偿 XCOORD, YCOORD, DEPTH
        x = parseFloat(((XCOORD0/2000 + parseFloat(XCOORD[i]))/1)).toFixed(1);
        y = parseFloat(parseFloat(DEPTH[i])/1).toFixed(1); // = (parseInt(parseFloat)/50).toFixed(0);
        z = parseFloat(((YCOORD0/3000 + parseFloat(YCOORD[i]))/1)).toFixed(1);
        //console.log(x,y,z);
        x = parseFloat(x - 4000);
        y = parseFloat(y - 1820);
        z = parseFloat(z + 3000);
        xyzCoord.push(new THREE.Vector3(x, y, z))
    }
    //xyzCoord.push(new THREE.Vector3(x, y+20, z))
    xyzCoord.push(new THREE.Vector3(0, y+30, 0))

    //console.log(xyzCoord)

    // 创建一个曲线
    const path = new THREE.CatmullRomCurve3(xyzCoord);

    //TubeGeometry构造函数的参数分别是：
    //path: 曲线路径。
    let tubularSegments =  64//: 管道分段的数量，决定了管道的平滑度。
    let radius = 5 //: 管道的半径。
    let radiusSegments = 8 //: 管道横截面分段的数量，决定了管道的圆度。
    let closed = false //: 布尔值，指示管道是否闭合。

    // 创建材质
    const tubeMaterial1 = new THREE.MeshBasicMaterial({ 
        color: 0xffffff,
        map: oilMeshViewApp1.flowingLineTexture1,
        side: THREE.DoubleSide,
        opacity: 0.9,
        transparent: true
    });

    const tubeMaterial2 = new THREE.MeshBasicMaterial({ 
        color: 0xffffff,
        side: THREE.DoubleSide,
        opacity: 0.2,
        transparent: true,
        //wireframe: true
    });

    // 使用曲线创建管状几何体
    const tubeGeometry = new THREE.TubeGeometry(path, tubularSegments, radius, radiusSegments, closed);

     // 添加组合材质
    const tubeMaterials = createMultiMaterialObject(tubeGeometry, [
        tubeMaterial1,
        tubeMaterial2
    ])

    // 创建网格
    const tube = tubeMaterials // new THREE.Mesh(tubeGeometry, tubeMaterials);

    tube.name = "well_subTube_"+id

    //tube.position.set(0,0,0)
    // 将网格添加到场景中
    scene.add(tube);
}

getWstuOutData()
//时间点 0 30 60 ... 720

/*    
const file = wstuOut[0];

if (file && file.type === 'text/plain') {
    let reader = new FileReader();

    // 6种事件模型
    // 开始读取时：
    reader.onloadstart = function(e) {
        console.log("开始读取", e);
    };
    // 正在读取：
    reader.onprogress = function(e) {
        console.log("正在读取",e);
    };
    // 读取出错时：
    reader.onerror = function(e) {
        console.log("读取出错",e);
    };
    // 读取中断时：
    reader.onabort = function(e) {
        console.log("读取中断",e);
    };
    // 读取成功时：

    reader.onload = function(e) {
        let content = e.target.result;
        console.log(content);
    };

    //4种文件读功能(方法、函数)
    //	reader.readAsText(file,"utf-8");
    //	reader.readAsBinaryString(file);  	// 将文件读取为二进制编码
    //  reader.readAsDataURL(file);  		// 将文件读取为DataURL
    //	reader.readAsText(none);  			// 终端读取操作

    reader.readAsText(file);

    // 读取完成，无论成功失败：
    reader.onloadend = function(e) {
        console.log("读取完成，无论成功失败",e);

    };

}
*/


let selectedModel = ref([0]);

function modelChangeFun(index){
    if(index<0){
        return
    }
    if(selectedModel.value.includes(index)){
        return
    }
    
    //console.log(modelItems.children.length)

    //const cNode = modelItems.getObjectByName ("cubeA")
    //const cubeAaxesHelper = new THREE.AxesHelper(50)
    //cNode.add(cubeAaxesHelper)
    //modelItems.remove(cNode)
    //modelItems.visible = false  //隐藏

    /*
    if( selectedModel.value == 0 && modelItems.children.length == 1){
        
        //modelItems = null
        model.visible = false; //设置为false，模型将不会被渲染到场景内
        //scene.getObjectByName("ObjName"); //返回第一个匹配的3d对象
        let oilMesh = scene.getObjectByName(url)

        //let box = new THREE.Box3().setFromObject( oilMesh );
        //let size = box.size();
        //console.log(size)//size包含模型x、y、z三个方向的最大值

        scene.remove(oilMesh)//将一个模型从场景中删除
        //scene.remove(oilMesh)//将一个模型从场景中删除
        oilMesh.traverse((obj) => {
            if (!obj.isMesh) return;
            //object3D是一个网格（Mesh），它有一个几何体和材质
            // 删除几何体和材质（如果它们不是被其他对象共享的）
            if (obj.geometry) {
                obj.geometry.dispose();
            }
            if (obj.material) {
                obj.material.dispose();
                // 如果材质有纹理，也释放纹理
                if (obj.material.map) {
                    obj.material.map.dispose();
                }
            }

        });
        model = null;
        selectedModel.value.shift();
    }*/

    btnDisabled.value = true

    //selectedModel.value = index
    selectedModel.value.push(index)

    setTimeout(()=>{
        addOilMesh(modelList.value[index]);
    },1)

}

// 相机移动动画 
const initTween = (targetX, targetY, targetZ)=> {
      // 需要保留this
      let initPosition = {
        x: oilMeshViewApp1.camera.position.x,
        y: oilMeshViewApp1.camera.position.y,
        z: oilMeshViewApp1.camera.position.z
      }
      let tween = new TWEEN.Tween(initPosition)
        .to({ x: targetX, y: targetY, z: targetZ }, 300)
        .easing(TWEEN.Easing.Sinusoidal.InOut)

      tween.onUpdate((pos)=>{
        let x = pos.x
        let y = pos.y
        let z = pos.z
        oilMeshViewApp1.camera.position.set(x, y, z)
        oilMeshViewApp1.controls.enabled = false
        oilMeshViewApp1.controls.target.set(0, 0, 0)
        oilMeshViewApp1.controls.update()
      })
      tween.onComplete(()=> {
        oilMeshViewApp1.controls.enabled = true
      })
      tween.start()

      //controls.target.set(0, 0, 0)
      //cssControl.target.set(0, 0, 0)
}

/**
    * 轴剖切传入模型 同时存在多个剖切面 需在渲染器设置localClippingEnabled 
    * @param {Object3D} modelObj        模型
    * @param {Array} clippingValue   滑块值 数组
    * @param {Array} axes            轴 数组
    *
*/
function applyClipping(modelObj, clippingValues, axes) {
    if (!modelObj || !Array.isArray(clippingValues) || !Array.isArray(axes)) return;

    // 确保剖切值数组和轴数组的长度相同
    if (clippingValues.length !== axes.length) {
        console.error("clippingValues和 axes 长度必须相同");
        return;
    }
    // 创建剖切平面数组
    const clippingPlanes = [];

    for (let i = 0; i < axes.length; i++) {
        // 确保剖切值在允许的范围内
        const value = Math.max(-3000, Math.min(clippingValues[i], 3000));
        let plane;
        if (axes[i] === "x") {
            plane = new THREE.Plane(new THREE.Vector3(1, 0, 0), -value);
        } else if (axes[i] === "z") {
            plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), -value);
        }
        if (plane) {
            clippingPlanes.push(plane);
        }
    }

    // 更新模型的剖切平面
    modelObj.traverse((child) => {
        if (child.isMesh) {
            child.material.clippingPlanes = clippingPlanes;
            child.material.needsUpdate = true;
        }
    });

    // 创建和更新剖切平面的辅助器
    if (planeHelpers) {
        planeHelpers.forEach((helper) => scene.remove(helper));
    }
    planeHelpers = clippingPlanes.map((plane) => {
        const helper = new THREE.PlaneHelper(plane, 1000, 0xffffff); // 使用更大的尺寸以覆盖整个模型
        // scene.add(helper);
        return helper;
    });

    // 遍历planeHelpers数组，将每个PlaneHelper对象添加到场景中
    planeHelpers.forEach(helper => {
        // scene.add(helper);
    });
}

let linesAndArrows = null;
let materialLine = null;
let arrowGeometry = null;
let arrowMaterial = null;
let arrowMesh = null;
let textMesh = null;
let TextMeshes = [];
let sceneScale = null;
let scale = false;

//传入模型显示标尺
function addBoundingBoxScale(model) {
    // 清除之前的标尺
    if (linesAndArrows) clearScale();
    const boundingBox = new THREE.Box3().setFromObject(model);
    const size = boundingBox.getSize(new THREE.Vector3());
    const center = boundingBox.getCenter(new THREE.Vector3());

    // 标尺线段的偏移量和箭头大小
    const offset = 1500; // 可以根据需要调整偏移量
    const arrowLength = 30; // 箭头的长度
    const arrowRadius = 8; // 箭头的半径
    const lineWidth = 10; // 线段的粗细

    // 创建线段
    const createScaleLine = (start, end, material) => {
        const geometry = new THREE.BufferGeometry().setFromPoints([start, end]);
        return new THREE.Line(geometry, material);
    };

    // 创建箭头
    const createArrow = (dir, origin) => {
        arrowGeometry = new THREE.ConeGeometry(arrowRadius, arrowLength, 32); // 增大了箭头的细节
        arrowMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
        arrowMesh = new THREE.Mesh(arrowGeometry, arrowMaterial);
        arrowMesh.position.copy(origin);
        arrowMesh.lookAt(dir);
        arrowMesh.rotateX(Math.PI / 2); // 根据需要调整箭头的方向
        return arrowMesh;
    };

    // 创建材质，增加了线段的粗细
    materialLine = new THREE.LineBasicMaterial({
        color: 0xffffff,
        linewidth: lineWidth,
    });

    // 创建线段和箭头
    linesAndArrows = {
        width: {
            line: createScaleLine(
                new THREE.Vector3(center.x + size.x / 2, (size.y / 2) + offset, center.z * 3),
                new THREE.Vector3(center.x - size.x / 2, (size.y / 2) + offset, center.z * 3),
                materialLine
            ),
            arrow1: createArrow(
                new THREE.Vector3(
                    center.x - size.x / 2 - arrowLength,
                    (size.y / 2) + offset,
                    center.z * 3
                ),
                new THREE.Vector3(center.x - size.x / 2, (size.y / 2) + offset, center.z * 3)
            ),
            arrow2: createArrow(
                new THREE.Vector3(
                    center.x + size.x / 2 + arrowLength,
                    (size.y / 2) + offset,
                    center.z * 3
                ),
                new THREE.Vector3(center.x + size.x / 2, (size.y / 2) + offset, center.z * 3)
            ),
        },
        height: {
            line: createScaleLine(
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y - size.y / 2,
                    center.z
                ),
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y + size.y / 2,
                    center.z
                ),
                materialLine
            ),
            arrow1: createArrow(
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y - size.y / 2 - arrowLength,
                    center.z
                ),
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y - size.y / 2,
                    center.z
                )
            ),
            arrow2: createArrow(
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y + size.y / 2 + arrowLength,
                    center.z
                ),
                new THREE.Vector3(
                    center.x - size.x / 2 - offset,
                    center.y + size.y / 2,
                    center.z
                )
            ),
        },
        depth: {
            line: createScaleLine(
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z - size.z / 2
                ),
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z + size.z / 2
                ),
                materialLine
            ),
            arrow1: createArrow(
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z - size.z / 2 - arrowLength
                ),
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z - size.z / 2
                )
            ),

            arrow2: createArrow(
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z + size.z / 2 + arrowLength
                ),
                new THREE.Vector3(
                    center.x + size.x / 2 + offset,
                    size.y / 2,
                    center.z + size.z / 2
                )
            ),
        },
    };

    // 创建标尺文字
    const createText = (text, position) => {
        const loader = new FontLoader();
        loader.load(import.meta.env.BASE_URL + 'public/assets/fonts/MicrosoftYaHei_Regular.json', function (font) {
            const textGeometry = new TextGeometry(text, {
                font: font,
                size: 96,
                //height: 0.05,
                depth: 0.05,
            });
            const textMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
            textMesh = new THREE.Mesh(textGeometry, textMaterial);
            // 调整位置
            textMesh.position.set(position.x, position.y, position.z);
            textMesh.visible = false;
            scene.add(textMesh);
            TextMeshes.push(textMesh);
        });
    };

    //添加标签到线段中点
    const addLabelToLine = (line) => {
        const start = new THREE.Vector3().fromBufferAttribute(
            line.geometry.attributes.position,
            0
        );
        const end = new THREE.Vector3().fromBufferAttribute(
            line.geometry.attributes.position,
            1
        );
        const midPoint = new THREE.Vector3().lerpVectors(start, end, 0.5);
        const distance = start.distanceTo(end).toFixed(2); // 计算距离并保留两位小数
        const distanceText = `${distance}m`; // 创建距离文本
        createText(distanceText, midPoint); // 在中点位置创建文本标签
    };
    // 添加线段和箭头到场景
    Object.values(linesAndArrows).forEach(({ line, arrow1, arrow2 }) => {
        addLabelToLine(line);
        scene.add(line);
        scene.add(arrow1);
        scene.add(arrow2);
    });

    // 开启标尺
    const showScale = () => {
        scale = true
        Object.values(linesAndArrows).forEach(({ line, arrow1, arrow2 }) => {
            // 设置初始状态
            line.scale.set(0, 0, 0); // 将线段长度缩放到0
            arrow1.visible = false; // 隐藏箭头
            arrow2.visible = false; // 隐藏箭头
            // 创建缩放动画
            new TWEEN.Tween(line.scale)
                .to({ x: 1, y: 1, z: 1 }, 1300) // 1秒内将线段长度缩放到1（原始长度）
                .easing(TWEEN.Easing.Quadratic.Out)
                .onStart(() => {
                    line.visible = true; // 开始动画时显示线段
                })
                .onUpdate(() => {
                    // 动画更新时调整箭头位置
                    arrow1.position.x =
                        line.geometry.attributes.position.array[3] * line.scale.x;
                    arrow2.position.x =
                        line.geometry.attributes.position.array[0] * line.scale.x;
                })
                .onComplete(() => {
                    arrow1.visible = true; // 动画完成后显示箭头
                    arrow2.visible = true; // 动画完成后显示箭头
                    TextMeshes.forEach((textMesh) => {
                        textMesh.visible = true;
                    });
                })
                .start();
        });
    };

    // 关闭标尺
    const hideScale = () => {
        if (!scale) return
        scale = false
        Object.values(linesAndArrows).forEach(({ line, arrow1, arrow2 }) => {
            // 创建缩放动画
            new TWEEN.Tween(line.scale)
                .to({ x: 0, y: 0, z: 0 }, 800) // 1秒内将线段长度缩放到0
                .easing(TWEEN.Easing.Quadratic.Out)
                .onUpdate(() => {
                    // 动画更新时调整箭头位置
                    TextMeshes.forEach((textMesh) => {
                        textMesh.visible = false;
                    });
                    arrow1.position.x =
                        line.geometry.attributes.position.array[3] * line.scale.x;
                    arrow2.position.x =
                        line.geometry.attributes.position.array[0] * line.scale.x;
                    arrow1.visible = false;
                    arrow2.visible = false;
                })
                .onComplete(() => {
                    arrow1.visible = false; // 动画完成后隐藏箭头
                    arrow2.visible = false; // 动画完成后隐藏箭头
                    line.visible = false; // 动画完成后隐藏线段
                })
                .start();
        });
    };

    return { showScale, hideScale };
}

//清除标尺
function clearScale() {
    // 移除所有标尺线、箭头和文本
    linesAndArrows.width.line && scene.remove(linesAndArrows.width.line);
    linesAndArrows.width.arrow1 && scene.remove(linesAndArrows.width.arrow1);
    linesAndArrows.width.arrow2 && scene.remove(linesAndArrows.width.arrow2);
    linesAndArrows.height.line && scene.remove(linesAndArrows.height.line);
    linesAndArrows.height.arrow1 && scene.remove(linesAndArrows.height.arrow1);
    linesAndArrows.height.arrow2 && scene.remove(linesAndArrows.height.arrow2);
    linesAndArrows.depth.line && scene.remove(linesAndArrows.depth.line);
    linesAndArrows.depth.arrow1 && scene.remove(linesAndArrows.depth.arrow1);
    linesAndArrows.depth.arrow2 && scene.remove(linesAndArrows.depth.arrow2);

    TextMeshes.forEach(textMesh => {
        scene.remove(textMesh);
        textMesh.geometry.dispose();
        textMesh.material.dispose();
    });
    TextMeshes = [];
}


function addBox(x=0,y=0,z=0){
    // 创建一个立方体
    const geometry = new THREE.BoxGeometry(80,80,80);
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);

    let cubeGeometry = new THREE.BoxGeometry(80, 80, 80);
    let cubeEdges = new THREE.EdgesGeometry(cubeGeometry, 1);
    let edgesMtl =  new THREE.LineBasicMaterial({color: 0xdd2222});
    edgesMtl.depthTest = true;// 深度测试，若开启则是边框透明的效果
    let cubeLine = new THREE.LineSegments(cubeEdges, edgesMtl);
    //将创建的线框加入的几何体中
    cube.add(cubeLine);

    cube.position.set(x, y, z);
    cube.name = "cube";
    scene.add(cube);

}

function addSphere(x=0,y=0,z=0){
    // 创建球体几何体
     //radius（必需）：球体的半径。
     //widthSegments（可选）：水平方向的分段数，决定了球体的水平切片数。
     //heightSegments（可选）：垂直方向的分段数，决定了球体的纵向切片数。
     //phiStart（可选）：纵向起始角度，以弧度表示。
     //phiLength（可选）：纵向角度范围，以弧度表示。
     //thetaStart（可选）：水平起始角度，以弧度表示。
     //thetaLength（可选）：水平角度范围，以弧度表示。
     const radius = 50;
     const widthSegments = 32;
     const heightSegments = 16;
     const geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);

     // 创建材质
     const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });

     // 创建球体网格
     const sphere = new THREE.Mesh(geometry, material);
     sphere.position.set(x,y,z)
     sphere.name = "sphere"
     scene.add(sphere);

     addArrows(sphere,true)

 }

 function addsprite (color, text, postion) {
     let sprite = null
     let spriteMaterial = addspriteMaterial(color, text)
     sprite = new THREE.Sprite(spriteMaterial)
     sprite.scale.set(450, 150, 50) // 大小缩放比例
     // 在使用透视投影相机对象的时候，精灵模型对象显示的大小和网格模型一样受距离相机的距离影响，也就是距离越远，显示效果越小
     // 创建精灵模型对象，不需要几何体geometry参数
     // 更新材质
     sprite.material = spriteMaterial
     // 控制精灵大小，比如可视化中精灵大小表征数据大小 位置 只需要设置x、y两个分量就可以
     // 更新车辆标签位置
     sprite.position.set(postion.x, postion.y, postion.z)
     // 将geometry的groupsNeedUpdate属性设置为true来告知渲染器该对象需要更新
     sprite.geometry.groupsNeedUpdate = true
     return sprite
 }

 function addspriteMaterial (color, text) { 
     let texture = new THREE.Texture(createSpriteCanvas(color, text))
     texture.needsUpdate = true
     // 创建精灵材质对象SpriteMaterial
     let spriteMaterial = new THREE.SpriteMaterial({
       transparent: true,
       map: texture // 设置精灵纹理贴图
     })
     return spriteMaterial
 }

 function createSpriteCanvas (color, text) {
     // 精灵平面（Sprite）是一个在3D场景中总是面对着相机的平面
     // 利用canvas绘制文字，作为sprite的材质 canvas 画布
     let canvas = document.createElement('canvas')
     // canvas 绘图上下文环境
     let context = canvas.getContext('2d')
     canvas.width = 120
     canvas.height = 40
     context.scale(2, 2)
     drawRect(context, color) // 绘制圆角矩形
     /* 字体颜色 */
     context.fillStyle = '#fff'
     // 减少阴影效果
     context.shadowColor = '#fff'
     context.shadowBlur = 1
     context.font = 'lighter 14px serif'
     /* 文字 */
     context.fillText(text, 1.9, 14.5)
     return canvas
 }

 function drawRect (ctx, color) {
     let width = 60
     let height = 20
     // 绘制一个圆角矩形
     strokeRoundRect(ctx, 1, 1, width - 2, height - 2, [2, 2, 2, 2], 1, color)
 }

 function strokeRoundRect (cxt, x, y, width, height, radius, lineWidth, strokeColor) {
     // 圆的直径必然要小于矩形的宽高
     if (2 * radius > width || 2 * radius > height) { return false }
     cxt.save()
     cxt.translate(x, y)
     // 绘制圆角矩形的各个边
     drawRoundRectPath(cxt, width, height, radius)
     cxt.lineWidth = lineWidth || 2 // 若是给定了值就用给定的值否则给予默认值2
     cxt.strokeStyle = strokeColor
     cxt.fillStyle = strokeColor + '88'
     cxt.fillRect(0, 0, width, height)
     cxt.stroke()
     cxt.restore()
 }

 function drawRoundRectPath (cxt, width, height, radius) {
     let r0 = radius[0]
     let r1 = radius[1]
     let r2 = radius[2]
     let r3 = radius[3]
     cxt.beginPath(0)
     // 从右下角顺时针绘制，弧度从0到1/2PI
     cxt.arc(width - r0, height - r0, r0, 0, Math.PI / 2)
     // 矩形下边线
     cxt.lineTo(r1, height)
     // 左下角圆弧，弧度从1/2PI到PI
     cxt.arc(r1, height - r1, r1, Math.PI / 2, Math.PI)
     // 矩形左边线
     cxt.lineTo(0, r2)
     // 左上角圆弧，弧度从PI到3/2PI
     cxt.arc(r2, r2, r2, Math.PI, Math.PI * 3 / 2)
     // 上边线
     cxt.lineTo(width - r3, 0)
     // 右上角圆弧
     cxt.arc(width - r3, r3, r3, Math.PI * 3 / 2, Math.PI * 2)
     // 右边线
     cxt.lineTo(width, height - r3)
     cxt.closePath()
}

function createBatchMesh(){
    //State 表达的是形态，而 Status 表达的是从一种形态转换成另一种形态的过程中，那些有显著特征的离散中间值。
    wellInfo.value.map((item,index)=>{
        wellInfo.value[index].showStatus = false;
        let { id, name, num, data, cpr } = item;
        let XCOORD = '0', YCOORD  = '0', DEPTH  = '0', STAGE  = '0';
        data[0].rest.map((it)=>{
            if(it.key==='XCOORD'){
                XCOORD = it.value
            }
            if(it.key==='YCOORD'){
                YCOORD = it.value
            }
            if(it.key==='DEPTH'){
                DEPTH = it.value
            }
            if(it.key==='STAGE'){
                STAGE = it.value
            }
        });
        
        // 位置矫正 补偿 XCOORD, YCOORD, DEPTH
        let x = ((XCOORD0/2000 + parseFloat(XCOORD))/1).toFixed(3);
        let y = 800; // = (parseInt(parseFloat)/50).toFixed(0);
        let z = ((YCOORD0/3000 + parseFloat(YCOORD))/1).toFixed(3);
        //console.log(x,y,z);
        x = x-4000;
        z = z+3000;
        let wellCyl = createMesh(x, y, z);
        wellCyl.name = "well_" + name;
        wellItems.add(wellCyl);

        addWellTube(parseInt(id));

        let sprite = addsprite(cpr==='SHUT'?'#333333':'#00ff00', 
            name + '-' + cpr.substr(0, 2),
            {x: x, y: 1600, z: z});
        sprite.name = "sprite_" + name;
        wellSprites.add(sprite);
        
    })

    // 油井 标牌 网格对象 批量添加到场景中
    scene.add(wellItems)
    //console.log("wellItems", wellItems)
    scene.add(wellSprites);
    //console.log("wellSprites", wellSprites)
    
}

// 创建网格模型
function createMesh(x=0,y=0,z=0) {
    //创建圆柱
    //属性	必须	描述
    //radiusTop	否	该属性定义圆柱顶部圆的半径，默认值是20
    //radiusBottom	否	该属性定义圆柱底部圆的半径，默认值是20
    //height	否	该属性定义圆柱的高度，默认是100
    //segmentsX	否	该属性指定沿X轴分成多少段，段数越多，圆柱越光滑，默认值是8
    //segmentsY	否	该属性指定沿Y轴分成多少段，段数越多，圆柱竖直方向分的面越多，默认值是1
    //openEnded	否	该属性用来指定圆柱顶部和底部是否封闭，默认false

    const geom = new THREE.CylinderGeometry(
      properties.radiusTop.value,
      properties.radiusBottom.value,
      properties.height.value,
      properties.segmentsX.value,
      properties.segmentsY.value,
      properties.openEnded
    )
    // 创建材质
    const meshMaterial = new THREE.MeshNormalMaterial({
      side: THREE.DoubleSide
    })
    const wireFrameMat = new THREE.MeshBasicMaterial({ wireframe: true })

    // 添加组合材质
    let meshCyl = createMultiMaterialObject(geom, [
      meshMaterial,
      wireFrameMat
    ])

    meshCyl.position.set(x, y, z);

    return meshCyl;
}


//油藏模型初始位置，缩放比例
let x=0,y=0,z=0,sx=1,sy=1,sz=1;
//井筒和标牌
let wellItems = new THREE.Object3D();
let wellSprites = new THREE.Object3D();


function isValidBufferGeometry(geometry) {
    if (!(geometry instanceof THREE.BufferGeometry)) {
      return false;
    }
  
    const position = geometry.attributes.position;
    if (!position) {
      return false;
    }
  
    // 检查顶点数组的长度是否合理
    if (position.count < 3) {
      return false;
    }
  
    // 检查顶点数组是否包含正确的数据类型
    if (position.array.constructor !== Float32Array) {
      return false;
    }
  
    // 可以继续检查其他属性，如法线、UV等
  
    return true;
}


function changeModelColor(n=0,a,b,len,r){
    optNum.value = n
    setTimeout(() => {
        changeModelOptions1(n,a,b,len,r)
    }, 1);
}

function changeModelOptions(){
    optNum.value = 10

    let meshCount = 0;
    let colorCube = parseInt(colorList[0]);
    let colorCount = 0;
    let color = new THREE.Color(colorCube);

    model.traverse((child) =>{
        if (child.isMark || child.isMarkChild || child.isLine || child.isSprite) return;
        if (child.isMesh) {
            //child.geometry.center();
            // child is an instance of Mesh
            //child.receiveShadow = true; 
            //child.frustumCulled = false;
            //模型阴影
            //child.castShadow = true;
            //模型自发光
            //child.material.emissive = child.material.color;
            //child.material.emissiveMap = child.material.map;
            if(!(meshCount%1)){
                colorCount++
                if(colorCount>colorList.length){
                    colorCount = 0;
                }
                colorCube = parseInt(colorList[colorCount]);
                color = new THREE.Color(colorCube);
                //console.log(meshCount)

                setTimeout(() => {
                    const colorBuffer = addColorBuffer(child.geometry);
                    //const colorBuffer = addColorBuffer(child.geometry);
                    
                    // 设置几何体attributes属性的颜色color属性
                    child.geometry.attributes.color = new THREE.BufferAttribute(colorBuffer, 3); 
                }, 1);

            }

            // 替换材质
            child.material = glassMaterial;

            meshCount++
            
        }
    })
}

function changeModelOptions1(n,a,b,len,r){
    let meshCount = 0;
    let colorCube = parseInt(colorList[0]);
    let colorCount = 0;
    let color = new THREE.Color(colorCube);

    model.traverse((child) =>{
        if (child.isMark || child.isMarkChild || child.isLine || child.isSprite) return;
        if (child.isMesh) {
            //child.geometry.center();
            // child is an instance of Mesh
            //child.receiveShadow = true; 
            //child.frustumCulled = false;
            //模型阴影
            //child.castShadow = true;
            //模型自发光
            //child.material.emissive = child.material.color;
            //child.material.emissiveMap = child.material.map;
            if(!(meshCount%1)){
                colorCount++
                if(colorCount>colorList.length){
                    colorCount = 0;
                }
                colorCube = parseInt(colorList[colorCount]);
                color = new THREE.Color(colorCube);
                //console.log(meshCount)

                //const colorBuffer = addColorBuffer(child.geometry);
                
                // 设置几何体attributes属性的颜色color属性
                
                setTimeout(() => {
                    const colorBuffer = addColorBuffer1(child.geometry,n,a,b,len,r);
                    child.geometry.attributes.color = new THREE.BufferAttribute(colorBuffer, 3); 
                }, 1);

            }

            // 替换材质
            //child.material = glassMaterial;

            meshCount++
            
        }
    })
}

//求 [n,m] 范围内的随机整数时，应该这样：
//Math.floor(Math.random() * (m - n + 1)) + n;


function randomNumArr(n=0, m =0){
    let num = Math.floor(Math.random() * (m - n + 1)) + n
    return num
}

function addColorBuffer1(geometry,n=1,a=1,b=1,len=100,r=3000){
    // 使用函数检查几何体
    const isValid = isValidBufferGeometry(geometry);
    if(!isValid){
        return
    }
    const pos = geometry.attributes.position;
    const count = pos.count; //顶点数量

        // 1. 计算模型y坐标高度差
    const xArr = [];//顶点所有x坐标，也就是地形高度
    const yArr = [];//顶点所有y坐标，也就是地形高度
    const zArr = [];//顶点所有z坐标，也就是地形高度
    for (let i = 0; i < count; i++) {
        xArr.push(pos.getX(i));//获取顶点x坐标，也就是地形高度
        yArr.push(pos.getY(i));//获取顶点y坐标，也就是地形高度
        zArr.push(pos.getZ(i));//获取顶点z坐标，也就是地形高度
    }

    xArr.sort();//数组元素排序，从小到大
    const minx = xArr[0];//x最小值
    const maxx = xArr[xArr.length - 1];//x最大值
    const xheight = maxx - minx; //山脉整体高度 

    yArr.sort();//数组元素排序，从小到大
    const miny = yArr[0];//y最小值
    const maxy = yArr[yArr.length - 1];//y最大值
    const yheight = maxy - miny; //山脉整体高度 

    zArr.sort();//数组元素排序，从小到大
    const minz = zArr[0];//z最小值
    const maxz = zArr[zArr.length - 1];//z最大值
    const zheight = maxz - minz; //山脉整体高度 

    //console.log("x:",minx,maxx,xheight);
    //console.log("y:",miny,maxy,yheight);
    //console.log("z:",minz,maxz,zheight);
    
    // 计算每个顶点的颜色值 // 2. 计算每个顶点的颜色值
    const colorsArr = [];
    
    // 根据顶点距离起点远近进行颜色插值计算
    let c1 = new THREE.Color(parseInt(colorsPalette[8].color)); //曲线起点颜色 蓝色 山谷颜色
    let c2 = new THREE.Color(parseInt(colorsPalette[0].color)); //曲线结束点颜色 红色 山顶颜色

    let xNum = [];
    let yNum = [];
    let zNum = [];
    //const len = 1000;
    //let r = 3000;

    //let a = 6;
    //let b = 5;
    
    for (let ix=1; ix < len; ix++) {
        let theta = Math.PI / ix; // 度角对应的弧度
        
        let x1 = r * Math.cos(a*ix + theta);
        //let y1 = r * Math.tan(theta)*Math.cos(theta); // 计算y坐标
        //let y1 = r * Math.cos(b*ix); // 计算y坐标
        let y1 = r * Math.sin(a*b*ix + theta);
        let z1 = r * Math.cos(b*ix)
        /*
        xNum.push(Number(randomNumArr(minx+x1, maxx-y1).toFixed(0)/100));
        yNum.push(Number(randomNumArr(miny+y1, maxy-y1).toFixed(0)/100));
        zNum.push(Number(randomNumArr(minz+z1, maxz-z1).toFixed(0)/100));
        */
        xNum.push(Number(randomNumArr(x1, x1).toFixed(0)/10))
        yNum.push(Number(randomNumArr(y1, y1).toFixed(0)/10))
        zNum.push(Number(randomNumArr(z1, z1).toFixed(0)/10))

    }

    //console.log(xNum,yNum,zNum)
    
    //xNum = Array.from({length: maxx-minx}, (i, j) => j+minx)
    //yNum = Array.from({length: maxy-miny}, (i, j) => j+miny)
    //zNum = Array.from({length: maxz-minz}, (i, j) => j+minz)

    //const START=2, END=5;
    //Array.from({length: END-START}, (x, i) => i+START)
    //yNum = Array.from({length: maxy-miny}, (x, j) => j+miny)

    //console.log(xNum,yNum,zNum)

    let num = n //randomNumArr(0, 8)
    //console.log(num)

    for (let i = 0; i < count; i++) {
        //const percent = i / count; //点索引值相对所有点数量的百分比
        // 红色分量从0到1变化，蓝色分量从1到0变化
        //colorsArr.push(percent, 0, 1 - percent); //蓝色到红色渐变色
        //根据顶点位置顺序大小设置颜色渐变
        //const c = c1.clone().lerp(c2, percent);//颜色插值计算
        //const c = new THREE.Color();
        //颜色插值结果，和c1一样rgb(1,0,0),50% c1 + 50% c2混合
        //c.lerpColors(c1,c2, 0.5);
        //colorsArr.push(c.r, c.g, c.b); 

        //梯度(gradient)、散度(divergence)与旋度(rotation)
        //梯度：标量求梯度得到矢量。
        //散度：矢量求散度得到标量。
        //旋度：矢量求旋度得到矢量。

        //当前高度和整体高度比值
        //const percent = (pos.getX(i) - minx) / xheight;
        //const c = c1.clone().lerp(c2, percent);//颜色插值计算
        //colorsArr.push(c.r, c.g, c.b); 

        //ymax: 2845 
        //ymin: 1750 

        //for(let y = miny; y < maxy; y+=(maxy/1000)){
        if(xNum.includes((pos.getX(i)).toFixed(0)/10)
            || yNum.includes((pos.getY(i)).toFixed(0)/10) 
            || zNum.includes((pos.getZ(i)).toFixed(0)/10)){
            c1 = new THREE.Color(parseInt(colorsPalette[num].color)); //曲线起点颜色 蓝色 山谷颜色
            c2 = new THREE.Color(parseInt(colorsPalette[num].color)); //曲线结束点颜色 红色 山顶颜色
        }else{
            c1 = new THREE.Color(parseInt("0xc0c0c0")); //曲线起点颜色 蓝色 山谷颜色
            c2 = new THREE.Color(parseInt("0xc0c0c0")); //曲线结束点颜色 红色 山顶颜色
        }
        //}

        //console.log(pos.getY(i))

        const percent = (pos.getY(i) - miny) / yheight;
        const c = c1.clone().lerp(c2, percent);//颜色插值计算
        colorsArr.push(c.r, c.g, c.b); 

        //const percent = (pos.getZ(i) - minz) / zheight;
        //const c = c1.clone().lerp(c2, percent);//颜色插值计算
        //colorsArr.push(c.r, c.g, c.b); 

    }
    const colorBuffer = new Float32Array(colorsArr);
    return colorBuffer
}


function addColorBuffer(geometry){
      // 使用函数检查几何体
      const isValid = isValidBufferGeometry(geometry);
      if(!isValid){
          return
      }
      const pos = geometry.attributes.position;
      const count = pos.count; //顶点数量
  
          // 1. 计算模型y坐标高度差
      const xArr = [];//顶点所有x坐标，也就是地形高度
      const yArr = [];//顶点所有y坐标，也就是地形高度
      const zArr = [];//顶点所有z坐标，也就是地形高度
      for (let i = 0; i < count; i++) {
          xArr.push(pos.getX(i));//获取顶点x坐标，也就是地形高度
          yArr.push(pos.getY(i));//获取顶点y坐标，也就是地形高度
          zArr.push(pos.getZ(i));//获取顶点z坐标，也就是地形高度
      }
  
      xArr.sort();//数组元素排序，从小到大
      const minx = xArr[0];//x最小值
      const maxx = xArr[xArr.length - 1];//x最大值
      const xheight = maxx - minx; //山脉整体高度 
  
      yArr.sort();//数组元素排序，从小到大
      const miny = yArr[0];//y最小值
      const maxy = yArr[yArr.length - 1];//y最大值
      const yheight = maxy - miny; //山脉整体高度 
  
      zArr.sort();//数组元素排序，从小到大
      const minz = zArr[0];//z最小值
      const maxz = zArr[zArr.length - 1];//z最大值
      const zheight = maxz - minz; //山脉整体高度 
  
      //console.log("x:",minx,maxx,xheight);
      //console.log("y:",miny,maxy,yheight);
      //console.log("z:",minz,maxz,zheight);
      
      // 计算每个顶点的颜色值 // 2. 计算每个顶点的颜色值
      const colorsArr = [];
      
      // 根据顶点距离起点远近进行颜色插值计算
      let c1 = new THREE.Color(parseInt(colorsPalette[8].color)); //曲线起点颜色 蓝色 山谷颜色
      let c2 = new THREE.Color(parseInt(colorsPalette[0].color)); //曲线结束点颜色 红色 山顶颜色
      for (let i = 0; i < count; i++) {
          //const percent = i / count; //点索引值相对所有点数量的百分比
          // 红色分量从0到1变化，蓝色分量从1到0变化
          //colorsArr.push(percent, 0, 1 - percent); //蓝色到红色渐变色
          //根据顶点位置顺序大小设置颜色渐变
          //const c = c1.clone().lerp(c2, percent);//颜色插值计算
          //const c = new THREE.Color();
          //颜色插值结果，和c1一样rgb(1,0,0),50% c1 + 50% c2混合
          //c.lerpColors(c1,c2, 0.5);
          //colorsArr.push(c.r, c.g, c.b); 
  
          //梯度(gradient)、散度(divergence)与旋度(rotation)
          //梯度：标量求梯度得到矢量。
          //散度：矢量求散度得到标量。
          //旋度：矢量求旋度得到矢量。
  
          //当前高度和整体高度比值
          //const percent = (pos.getX(i) - minx) / xheight;
          //const c = c1.clone().lerp(c2, percent);//颜色插值计算
          //colorsArr.push(c.r, c.g, c.b); 
  
          //ymax: 2845 
          //ymin: 1750 
  
          if(pos.getY(i)>=1700 && pos.getY(i)<2000 ){
              c1 = new THREE.Color(parseInt(colorsPalette[8].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[8].color)); //曲线结束点颜色 红色 山顶颜色
          } else if(pos.getY(i)>=2000 && pos.getY(i)<2300 ){
              c1 = new THREE.Color(parseInt(colorsPalette[7].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[7].color)); //曲线结束点颜色 红色 山顶颜色
          } else if(pos.getY(i)>=2300 && pos.getY(i)<2400 ){
              c1 = new THREE.Color(parseInt(colorsPalette[6].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[6].color)); //曲线结束点颜色 红色 山顶颜色
          }  else if(pos.getY(i)>=2400 && pos.getY(i)<2500 ){
              c1 = new THREE.Color(parseInt(colorsPalette[5].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[5].color)); //曲线结束点颜色 红色 山顶颜色
          }  else if(pos.getY(i)>=2500 && pos.getY(i)<2600 ){
              c1 = new THREE.Color(parseInt(colorsPalette[4].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[4].color)); //曲线结束点颜色 红色 山顶颜色
          } else if(pos.getY(i)>=2600 && pos.getY(i)<2700 ){
              c1 = new THREE.Color(parseInt(colorsPalette[3].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[3].color)); //曲线结束点颜色 红色 山顶颜色
          } else if(pos.getY(i)>=2700 && pos.getY(i)<2800 ){
              c1 = new THREE.Color(parseInt(colorsPalette[2].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[1].color)); //曲线结束点颜色 红色 山顶颜色
          } else if(pos.getY(i)>=2800 && pos.getY(i)<2900 ){
              c1 = new THREE.Color(parseInt(colorsPalette[1].color)); //曲线起点颜色 蓝色 山谷颜色
              c2 = new THREE.Color(parseInt(colorsPalette[0].color)); //曲线结束点颜色 红色 山顶颜色
          }
  
          //console.log(pos.getY(i))
  
          const percent = (pos.getY(i) - miny) / yheight;
          const c = c1.clone().lerp(c2, percent);//颜色插值计算
          colorsArr.push(c.r, c.g, c.b); 
  
          //const percent = (pos.getZ(i) - minz) / zheight;
          //const c = c1.clone().lerp(c2, percent);//颜色插值计算
          //colorsArr.push(c.r, c.g, c.b); 
  
      }
      const colorBuffer = new Float32Array(colorsArr);
      return colorBuffer
}


function addOilMesh(url=""){
    setTimeout(() => {
        addLoading()
        /*AnimCam.animateCamera(camera, 
            controls, 
            { x: camera.position.x, y: camera.position.y, z: camera.position.z }, 
            { x: 3, y: 3, z: 3 }, 
        300, () => {})*/

        //initTween( camera.position.x+1, camera.position.y+1, camera.position.z+1 )

    }, 1);

    // 加载BrickMesh public中的模型文件./model.glb
    gltfLoader.load(url, (gltf) => {
        model = gltf.scene;
        model.name = url
        model.castShadow = true;

        //console.log('gltf',gltf);
        //gltf.scene获取gltf文件包含的模型数据
        //gltf模型添加到三维场景中

        //WebGL 使用 OpenGL 惯例，其中 Y 轴朝上，Z 轴朝向观看者。WebGPU 使用 Metal 惯例，其中 Y 轴在屏幕之外，Z 轴在屏幕范围外。
        //请注意，在帧缓冲区坐标、视口坐标和片段/像素坐标中，Y 轴方向为向下。在剪辑空间中，Y 轴方向仍然与 WebGL 中的方向相同。
        x = 3850/1, y = -1800/1, z= 1750/1,  
        //sx = 0.001, sy = 0.001, sz = 0.001;
        // 几何体沿着x轴平移
        model.translateX(x);
        // 几何体沿着y轴平移
        model.translateY(y);
        // 几何体沿着Z轴平移
        model.translateZ(y);

        // 修改模型的缩放
        model.scale.set(sx, sy, sz); // 设置缩放比例 (x, y, z)
        
        // 几何体绕着x轴旋转90度
        model.rotateY(-Math.PI / 12);

        // 几何体绕着x轴旋转90度
        model.rotateX(-Math.PI);
        model.rotateZ(-Math.PI);

        model.position.z += 1750*2.5

        let meshCount = 0;
        let colorCube = parseInt(colorList[0]);
        let colorCount = 0;
        let color = new THREE.Color(colorCube);

        model.traverse((child) =>{
            if (child.isMark || child.isMarkChild || child.isLine || child.isSprite) return;
            if (child.isMesh) {
                //child.geometry.center();
                // child is an instance of Mesh
                child.receiveShadow = true; 
                child.frustumCulled = false;
                //模型阴影
                child.castShadow = true;
                //模型自发光
                child.material.emissive = child.material.color;
                child.material.emissiveMap = child.material.map;
                if(!(meshCount%1)){
                    colorCount++
                    if(colorCount>colorList.length){
                        colorCount = 0;
                    }
                    colorCube = parseInt(colorList[colorCount]);
                    color = new THREE.Color(colorCube);
                    //console.log(meshCount)

                    setTimeout(() => {
                        const colorBuffer = addColorBuffer(child.geometry);
                    
                        // 设置几何体attributes属性的颜色color属性
                        child.geometry.attributes.color = new THREE.BufferAttribute(colorBuffer, 3); 
                    }, 1);
     
                }

                // 替换材质
                child.material = glassMaterial;

                meshCount++
            }
        })

        initExplodeModel(model)
        //applyClipping(model, PlaneArr, ["x","y","z"])
        //sceneScale = addBoundingBoxScale(model)
        //sceneScale.showScale()
        //sceneScale.hideScale()
    })
}

const addArrows = (meshModel, needsArrows=false)=> {
    
    if (!needsArrows) return;

    let activeMesh = meshModel;
    activeMesh.children = [];

    //在 three.js 中有THREE.Mesh 网格、THREE.Points 点、THREE.Line 线条等模型
    //Mesh 网格模型创建的物体是由一个个小三角形组成，这些小三角形又是由三个点确定，需要三个确定的位置，即确定的 xyz
    //Points 模型创建的物体是由一个个点构成，每个点都有自己的位置，Points 相当于点的集合。
    //Line 模型创建的物体是连续的线条，这些线可以理解为是按顺序把所有点连接起来。
    //不管是哪一种模型，它们都有一个共同点，就是都离不开点，每一个点都有确定的 x y z，
    //BoxGeometry、SphereGeometry 帮我们封装了对这些点的操作，我们只需要告诉它们长宽高或者半径这些信息，它就会帮我创建一个默认的几何体。而 BufferGeometry 就是完全由我们自己去操作点信息的方法，我们可以通过它去设置每一个点的位置，即 position；每一个点的颜色，即 color；每一个点的法向量 normal 等。

    //Face3( a, b, c, normal, color, materialIndex )
    //a — 顶点索引A。
    //b — 顶点索引B。
    //c — 顶点索引C。
    //normal — 面法向量或顶点法向量数组。
    //color — 面颜色或顶点颜色的数组。
    //materialIndex — 材料索引。

    //每个“face”被指定为顶点列表中三个顶点的索引--而不是每个面的显式JavaScript对象
    //几何中的三个顶点的每一个三重奏都将被认为是一个唯一的三角形。如果要在多个三角形之间共享相同的顶点，则需要索引。

    /*
    for (var f = 0, fl = activeMesh.geometry.faces.length; f < fl; f++) {
        var face = activeMesh.geometry.faces[f];
        var centroid = new THREE.Vector3(0, 0, 0);
        centroid.add(activeMesh.geometry.vertices[face.a]);
        centroid.add(activeMesh.geometry.vertices[face.b]);
        centroid.add(activeMesh.geometry.vertices[face.c]);
        centroid.divideScalar(3);

        var arrow = new THREE.ArrowHelper(
                face.normal,
                centroid,
                2,
                0x3333FF,
                0.5,
                0.5);
        activeMesh.add(arrow);
    }*/

    //几何体（Geometry）是一个数据结构，包含了用于描述三维物体的基本信息，如顶点（vertices）、面（faces）和它们的关联属性（例如颜色、法线、纹理坐标等）。
    //将几何体与材质（Material）相结合，我们可以创建出形状丰富、颜色各异的三维物体。
    /*
    在 Three.js 中，几何体（Geometry）是一个数据结构，用于描述三维物体的基本信息。Geometry 的主要属性如下：
    vertices： 顶点数组，用于存储几何体的顶点。顶点是由 THREE.Vector3 对象表示的三维空间中的点，它们定义了物体的形状。
    faces： 面数组，用于存储几何体的面。面是由顶点组成的多边形，它们共同定义了几何体的表面。在 Three.js 中，面通常由 THREE.Face3 对象表示，表示一个由三个顶点组成的三角形。
    faceVertexUvs： 一个二维数组，用于存储每个面的纹理坐标。纹理坐标是每个顶点在纹理图像上的二维坐标，由 THREE.Vector2 对象表示。纹理坐标用于将纹理映射到几何体的表面。
    vertexNormals： 顶点法线数组。顶点法线是由 THREE.Vector3 对象表示的单位向量，指向顶点表面的法线方向。顶点法线用于光照计算和平滑着色。
    boundingBox： 几何体的轴对齐边界框（Axis-Aligned Bounding Box，AABB）。边界框是一个由最小和最大点组成的立方体，它紧密包围几何体。边界框用于快速剔除和碰撞检测等场景优化。
    boundingSphere： 几何体的包围球。包围球是一个半径最小的球体，它完全包含几何体。包围球同样用于快速剔除和碰撞检测等场景优化。
    colors： 顶点颜色数组。顶点颜色用于为每个顶点分配颜色值，它们可以在着色器中用于插值计算。顶点颜色由 THREE.Color 对象表示。
    morphTargets： 几何体的形状目标（Morph Targets）数组。形状目标是一组与原始几何体具有相同顶点数量的几何体，它们用于实现形状变形动画。
    */

    /*
    // 创建一个空的几何体对象
    const geometry = new THREE.Geometry();
    ​
    // 定义三个顶点
    const v1 = new THREE.Vector3(0, 0, 0);
    const v2 = new THREE.Vector3(1, 0, 0);
    const v3 = new THREE.Vector3(0, 1, 0);
    ​
    // 将顶点添加到几何体中
    geometry.vertices.push(v1);
    geometry.vertices.push(v2);
    geometry.vertices.push(v3);
    ​
    // 创建一个面，使用顶点的索引定义
    const face = new THREE.Face3(0, 1, 2);
    ​
    // 将面添加到几何体中
    geometry.faces.push(face);
    ​
    // 更新法线（这对于渲染和光照计算非常重要）
    geometry.computeFaceNormals();
    ​
    // 创建一个材质
    const material = new THREE.MeshBasicMaterial({color: 0xff0000, side: THREE.DoubleSide});
    ​
    // 创建一个网格对象
    const triangle = new THREE.Mesh(geometry, material);
    ​
    // 添加到场景中
    scene.add(triangle);

    */

    //const geometry = new THREE.BufferGeometry();

    // specify vertex positions
    //geometry.setAttribute( 'position', 
    //new THREE.BufferAttribute( new Float32Array( [
    //    -5, 0, 0, // vertex 1
    //    5, 0, 0,  // vertex 2 
    //    0, 5, 0   // vertex 3
    //], 3 ) )
    //);

    // specify triangles, as triplets of indexes into the vertex list.
    //geometry.setIndex( new THREE.BufferAttribute( [ 0, 1, 2 ], 1 ) );

    //顶点位置position、顶点颜色color、顶点UV坐标uv
    //normal 设置点法向量 主要和光照相关，光线与表面夹角角度的不一样，会导致亮度等也不一样 法向量必须归一化
    //position 设置点位置  
    //color 设置点颜色 每一个点都可以设置颜色，颜色通过 rgb 值来设置，r g b 分别取 0-1之间的值。
    //uv
    //index 设置 index 可以理解 index 为 positions 数组中的第n-1个点，如下每一行注释后面就是该点的 index 值。


    //与常规几何体（Geometry）相比，BufferGeometry 使用类型化数组（Typed Arrays）存储顶点、面和其他属性，可以显著减少内存占用和渲染时间。
    //three.js辅助开发的类，就是xyz三维坐标系AxesHelper,这节课给大家介绍一个新的辅助类，three.js的箭头ArrowHelper 借助小球、箭头等方式可视化你的几何数据，通过具象的图像，有助于理解抽象的代码。
    
    const p = activeMesh.geometry.attributes.position;
    const n = activeMesh.geometry.attributes.normal;
    const count = p.count;//顶点数量
    for (let i = 0; i < count; i++) {
        // 顶点位置O
        const O = new THREE.Vector3(p.getX(i), p.getY(i), p.getZ(i));
        // 顶点位置O对应的顶点法线
        const dir = new THREE.Vector3(n.getX(i), n.getY(i), n.getZ(i));
        // 箭头可视化顶点法线
        const arrowHelper = new THREE.ArrowHelper(dir, O, 10, 0x0000ff, 0.5, 0.5);
        activeMesh.add(arrowHelper);
    }

}

const deleteModel = (index)=>{
    if(index<0){
        return
    }

    //console.log(modelItems.children.length)

    //const cNode = modelItems.getObjectByName ("cubeA")
    //const cubeAaxesHelper = new THREE.AxesHelper(50)
    //cNode.add(cubeAaxesHelper)
    //modelItems.remove(cNode)
    //modelItems.visible = false  //隐藏

    if( selectedModel.value.includes(index) && modelItems.children.length ){
        
        //modelItems = null
        if(model){
            //model.visible = false; //设置为false，模型将不会被渲染到场景内
        }
        
        //scene.getObjectByName("ObjName"); //返回第一个匹配的3d对象
        let oilMesh = scene.getObjectByName(modelList.value[index])

        //let box = new THREE.Box3().setFromObject( oilMesh );
        //let size = box.size();
        //console.log(size)//size包含模型x、y、z三个方向的最大值

        //scene.remove(oilMesh)//将一个模型从场景中删除
        modelItems.remove(oilMesh)
        //scene.remove(oilMesh)//将一个模型从场景中删除
        oilMesh.traverse((obj) => {
            if (!obj.isMesh) return;
            //object3D是一个网格（Mesh），它有一个几何体和材质
            // 删除几何体和材质（如果它们不是被其他对象共享的）
            if (obj.geometry) {
                obj.geometry.dispose();
            }
            if (obj.material) {
                obj.material.dispose();
                // 如果材质有纹理，也释放纹理
                if (obj.material.map) {
                    obj.material.map.dispose();
                }
            }

        });
        //model = null;
        //selectedModel.value.shift();
        //const i = selectedModel.value.indexOf(index);
        //if (i > -1) {
        //    selectedModel.value.splice(i, 1);
        //}
        selectedModel.value = selectedModel.value.filter(i => i !== index);
        
    }


}

/*
实现原理
初始化数据：遍历计算每个mesh的中心点，保存在userData上
爆炸计算逻辑：以当前中心的到原点的矢量A作为爆炸方向，|A| * d(爆炸系数 ) 作为爆炸距离；
渲染：在循环渲染中每次更改 d ,这样就可以实现爆炸动画效果了
*/

// 初始化爆炸数据保存到每个mesh的userdata上
function initExplodeModel(modelObject) {
  if (!modelObject) return;

  // 计算模型中心
  const explodeBox = new THREE.Box3();
  explodeBox.setFromObject(modelObject);
  const explodeCenter = getWorldCenterPosition(explodeBox);

  const meshBox = new THREE.Box3();

  // 遍历整个模型，保存数据到userData上，以便爆炸函数使用
  modelObject.traverse(function (value) {
    if (value.isLine || value.isSprite) return;
    if (value.isMesh) {
      meshBox.setFromObject(value);

      const meshCenter = getWorldCenterPosition(meshBox);
      // 爆炸方向
      value.userData.worldDir = new THREE.Vector3()
        .subVectors(meshCenter, explodeCenter)
        .normalize();
      // 爆炸距离 mesh中心点到爆炸中心点的距离
      value.userData.worldDistance = new THREE.Vector3().subVectors(meshCenter, explodeCenter);
      // 原始坐标
      value.userData.originPosition = value.getWorldPosition(new THREE.Vector3());
      // mesh中心点
      value.userData.meshCenter = meshCenter.clone();
      value.userData.explodeCenter = explodeCenter.clone();
    }
  });
}

// 模型爆炸函数 
const explodeModel = (model, scalar) => {
  model.traverse(function (value) {
    // @ts-ignore
    if (!value.isMesh || !value.userData.originPosition) return;
    const distance = value.userData.worldDir
      .clone()
      .multiplyScalar(value.userData.worldDistance.length() * scalar);
    const offset = new THREE.Vector3().subVectors(
      value.userData.meshCenter,
      value.userData.originPosition
    );
    const center = value.userData.explodeCenter;
    const newPos = new THREE.Vector3().copy(center).add(distance).sub(offset);
    const localPosition = value.parent?.worldToLocal(newPos.clone());
    localPosition && value.position.copy(localPosition);
  });
};
//辅助代码
function getWorldCenterPosition(box, scalar = 0.5) {
  return new THREE.Vector3().addVectors(box.max, box.min).multiplyScalar(scalar);
}

const onChangeModelView = (val) => {
    modelItems.children.map((item)=>{
        explodeModel(item, val)
    })
}


function isMeshType(object) {
    return object?.type === 'Mesh'
}

function displayTips (object) {
    
    let position = object.name.search(/sprite_/i);
    if(position>-1){
        let nameStr = object.name;
        let nameStrArr = nameStr.split("_");
        
        wellInfo.value.map((item,index)=>{
            let { id, name, num, data, cpr } = item;
            if(nameStrArr[1] == name){
                wellInfo.value[index].showStatus = true;
                //console.log(nameStrArr[1],wellInfo.value[index].showStatus)
                objectMesh.name = name;
            }else{
                wellInfo.value[index].showStatus = false;
            }
        })
    }
    
}

function renderDiv (arr) {
    let object = arr[0]
    if(object.name == ""){
        wellInfo.value.map((item,index)=>{
            //let { id, name, num, data, cpr } = item;
            wellInfo.value[index].showStatus = false;
        })
        return 0;
    }
    
    // 获取窗口的一半高度和宽度
    let webglApp = document.querySelector('#webgl-app1')
    let halfWidth = webglApp.offsetWidth / 2
    let halfHeight = webglApp.offsetHeight / 2
    // let halfWidth = window.innerWidth / 2
    // let halfHeight = window.innerHeight / 2
    // 逆转相机求出二维坐标
    let vector = object.position.clone().project(camera)
    let left = vector.x * halfWidth + halfWidth - 172
    let top = -vector.y * halfHeight + halfHeight - object.position.y + 1620
    // 修改 div 的位置
    // document.getElementById('label').style.cssText = 'position: absolute;left:' + left + 'px;top:' + top + 'px'
    // 显示模型信息
    // document.getElementById('label').innerHTML = '<p style="color: blue;">模型名称:' + object.name + '</p>'
    let tipsDom = document.querySelector('#tips')
    tipsDom.style.cssText = 'left:' + left + 'px;top:' + top + 'px'
    displayTips(object)
}

// 更新div的位置
const renderLabelDiv = (object)=> {
      // 获取窗口的一半高度和宽度
      //let halfWidth = window.innerWidth / 2
      //let halfHeight = window.innerHeight / 2

      // 逆转相机求出二维坐标
      //let vector = object.position.clone().project(camera)

      //let left = mouse.x || vector.x * halfWidth + halfWidth
      //let top = mouse.y || -vector.y * halfHeight + halfHeight - object.position.y

      // 修改 div 的位置
      //document.getElementById('label').style.cssText = 'left:' + left + 'px;top:' + top + 'px'
      // console.log('left:' + (vector.x * halfWidth + halfWidth) + 'px;top:' + (-vector.y * halfHeight + halfHeight - object.position.y) + 'px')
      // 显示模型信息
      objectMesh.name = object.name;
      document.querySelector("#label").style.display = "block"
}

/**
 * 通过模型组件获取整个模型
 * @param {*} obj 通过模型的一部分获取整个模型
 * @returns {*} 整体模型
 */
const partToMesh = (obj,scene) => {

    if (obj === scene || obj.userData && obj.userData.Server === true) { // 场景或服务端模型
        return obj;
    }

    // 判断obj是否是模型的一部分
    let model = obj;
    let isPart = false;

    while (model) {
        if (model === scene) {
            break;
        }
        if (model.userData && model.userData.Server === true) {
            isPart = true;
            break;
        }

        model = model.parent;
    }

    if (isPart) {
        return model;
    }

    return obj;
}

let waitTime = 16.6; // GPU 16.6毫秒检测一次，提升性能
let oldTime = 0;
let line
const renderTarget = (renderer, scene, camera)=>{
    // 鼠标在画布外面的处理流程
    if (!isIn) {
        return;
    }
    // 间隔一段时间执行一次，提高性能
    let now = new Date().getTime();
    if (now - oldTime < waitTime) {
        return;
    }
    oldTime = now;

    const { width, height } = renderer.domElement;

    const depthMaterial = new THREE.ShaderMaterial({
        vertexShader: DepthVertexShader,
        fragmentShader: DepthFragmentShader,
        uniforms: {
            far: {
                value: camera.far
            }
        }
    });

    /*
    重要说明：
    a.gl_Position.z是相机空间中的深度，是线性的，范围从cameraNear到cameraFar。可以直接使用着色器varying变量进行插值。
    b.gl_Position.z/far的原因是，将值转换到0~1范围内，便于作为颜色输出。
    c. 不能使用屏幕空间中的深度，透视投影后，深度变为-1~1，大部分非常接近1（0.9多），不是线性的，几乎不变，输出的颜色几乎不变，非常不准确。
    d. 在片元着色器中获取深度方法：相机空间深度为gl_FragCoord.z，屏幕空间深度为gl_FragCoord.z/gl_FragCoord.w。
    e. 上述描述都是针对透视投影，正投影中gl_Position.w为1，使用相机空间和屏幕空间深度都是一样的。
    f. 为了尽可能准确输出深度，采用rgb三个分量输出深度。gl_Position.z/far范围在0~1，乘以0xffffff，转换为一个rgb颜色值，r分量1表示65535，g分量1表示255，b分量1表示1。
    */

    let renderTarget1 = new THREE.WebGLRenderTarget(width, height);
    // pixel是Uint8Array(4)，分别保存rgba颜色的四个通道，每个通道取值范围是0~255。
    let pixel = new Uint8Array(4);

    let nearPosition = new THREE.Vector3(); // 鼠标屏幕位置在near处的相机坐标系中的坐标
    let farPosition = new THREE.Vector3(); // 鼠标屏幕位置在far处的相机坐标系中的坐标
    let world = new THREE.Vector3(); // 通过插值计算世界坐标

    line = new THREE.Line3(nearPosition, farPosition);
    let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(new THREE.Vector3(0, 1, 0), new THREE.Vector3());

    // 记录旧属性
    const oldBackground = scene.background;
    const oldOverrideMaterial = scene.overrideMaterial;
    const oldRenderTarget = renderer.getRenderTarget();

    // ---------------------------- 1. 使用GPU判断选中的物体 -----------------------------------

    scene.background = null; // 有背景图，可能导致提取的颜色不准
    scene.overrideMaterial = null;
    renderer.setRenderTarget(renderTarget1); 
    changePickMaterial();

    //绘制并读取像素
    renderer.clear();
    renderer.render(scene, camera);
    // offsetX和offsetY是鼠标位置，width是画布宽度，height是画布高度
    renderer.readRenderTargetPixels(renderTarget1, offsetX, height - offsetY, 1, 1, pixel); //读取鼠标所在位置颜色

    //还原原来材质，并获取选中物体
    const currentColor = pixel[0] * 0xffff + pixel[1] * 0xff + pixel[2];

    let selected = null;

    scene.traverseVisible(n =>{
        if (!(n instanceof THREE.Mesh)) {
            return;
        }
        if (n.pickMaterial && n.pickColor === currentColor) { //颜色相同
            selected = n; //鼠标所在位置的物体
        }
        if(n.oldMaterial) {
            n.material = n.oldMaterial;
            delete n.oldMaterial;
        }
    });

    // ------------------------- 2. 使用GPU反算世界坐标 ----------------------------------

    scene.overrideMaterial = depthMaterial;

    renderer.clear();
    renderer.render(scene, camera);
    renderer.readRenderTargetPixels(renderTarget1, offsetX, height - offsetY, 1, 1, pixel);

    let cameraDepth = 0;

    const deviceX = offsetX / width * 2 - 1;
    const deviceY = offsetY / height * 2 + 1;

    // TODO: nearPosition和farPosition命名反了
    nearPosition.set(deviceX, deviceY, 1); // 屏幕坐标系：(0, 0, 1)
    nearPosition.applyMatrix4(camera.projectionMatrixInverse); // 相机坐标系：(0, 0, -far)

    farPosition.set(deviceX, deviceY, -1); // 屏幕坐标系：(0, 0, -1)
    farPosition.applyMatrix4(camera.projectionMatrixInverse); // 相机坐标系：(0, 0, -near)

    if (pixel[2] !== 0 || pixel[1] !== 0 || pixel[0] !== 0) { // 鼠标位置存在物体
        let hex = (pixel[0] * 65535 + pixel[1] * 255 + pixel[2]) / 0xffffff;

        if (pixel[3] === 0) {
            hex = -hex;
        }

        cameraDepth = -hex * camera.far; // 相机坐标系中鼠标所在点的深度（注意：相机坐标系中的深度值为负值）

        const t = (cameraDepth - nearPosition.z) / (farPosition.z - nearPosition.z);

        world.set(
            nearPosition.x + (farPosition.x - nearPosition.x) * t,
            nearPosition.y + (farPosition.y - nearPosition.y) * t,
            cameraDepth
        );
        world.applyMatrix4(camera.matrixWorld);
    } else { // 鼠标位置不存在物体，则与y=0的平面的交点
        nearPosition.applyMatrix4(camera.matrixWorld); // 世界坐标系近点
        farPosition.applyMatrix4(camera.matrixWorld); // 世界坐标系远点
        line.set(nearPosition, farPosition);
        plane.intersectLine(line, world);
    }

    // 还原原来的属性
    scene.background = oldBackground;
    scene.overrideMaterial = oldOverrideMaterial;
    renderer.setRenderTarget(oldRenderTarget);

    // ------------------------------- 3. 输出碰撞结果 --------------------------------------------

    if (selected && selectMode === 'whole') { // 选择整体
        selected = partToMesh(selected, renderer, scene, camera);
    }

    gpuPick = {
        object: selected, // 碰撞到的物体，没碰到为null
        point: world, // 碰撞点坐标，没碰到物体与y=0平面碰撞
        distance: cameraDepth // 相机到碰撞点距离
    }


    if(selected instanceof THREE.Mesh){
      if (selected) {
        //const target = selected;
        //controls.attach(target); // 绑定controls和方块
        //scene.add(controls);
        //console.log(selected)
        outlineObj([selected.parent.parent],renderer, scene, camera)
      }
    }

}

let maxHexColor = 1;
let selectMode = 'whole';
const changePickMaterial = ()=>{
  
  //更换选取材质
  scene.traverseVisible(n =>{
      if (!(n instanceof THREE.Mesh)) {
          return;
      }
      n.oldMaterial =n.material;
      if (n.pickMaterial) { //已经创建过选取材质了
          n.material =n.pickMaterial;
          return;
      }
      let material = new THREE.ShaderMaterial({
          vertexShader: PickVertexShader,
          fragmentShader: PickFragmentShader,
          uniforms: {
              pickColor: {
                  value: new THREE.Color(maxHexColor)
              }
          }
      });
      n.pickColor =maxHexColor;
      maxHexColor++;
      n.material = n.pickMaterial = material;
  });
}



let object = {}
let hideObjects = []
let maskBuffer = null
let edgeBuffer = null
let quad = null
let maskMaterial = null
let edgeMaterial = null
let copyMaterial = null
const onObjectSelected = (obj,renderer,scene,camera)=> {
    if (!obj) {
        return;
    }
    // 禁止选中场景和相机
    if (obj === scene || obj === camera) {
        return;
    }

    // 禁止选中精灵
    // TODO: 暂时不绘制精灵边框。以后让精灵选中边框在正确的位置上。
    if (obj instanceof THREE.Sprite) {
        return;
    }

    // 不允许选中文字
    if (obj.userData && (obj.userData.type === 'text' || obj.userData.type === 'pointMarker')) {
        return;
    }

    let size = new THREE.Vector2();
    renderer.getDrawingBufferSize(size);

    let width = size.x * 2;
    let height = size.y * 2;
    let geometry = new THREE.PlaneGeometry( width, height, 32 );
    let material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
    quad = new THREE.Mesh( geometry, material );
    quad.frustumCulled = false;
    //scene.add( quad );

    let params = {
        minFilter: THREE.LinearFilter,
        magFilter: THREE.LinearFilter,
        format: THREE.RGBAFormat,
        antialias: true
    };

    maskBuffer = new THREE.WebGLRenderTarget(width, height, params);
    maskBuffer.texture.generateMipmaps = false;

    edgeBuffer = new THREE.WebGLRenderTarget(width, height, params);
    edgeBuffer.texture.generateMipmaps = false;

    
    maskMaterial = new THREE.ShaderMaterial({
        vertexShader: MaskVertex,
        fragmentShader: MaskFragment,
        depthTest: false
    });

    // const selectedColor = global.app.storage.selectedColor;
    // const selectedThickness = global.app.storage.selectedThickness;

    

    edgeMaterial = new THREE.ShaderMaterial({
        vertexShader: EdgeVertex,
        fragmentShader: EdgeFragment,
        uniforms: {
            maskTexture: {
                value: maskBuffer.texture
            },
            texSize: {
                value: new THREE.Vector2(width, height)
            },
            color: {
                value: new THREE.Color(0,0,0)
            },
            thickness: {
                type: 'f',
                value: 2
            },
            transparent: true
        },
        depthTest: false
    });

    copyMaterial = new THREE.ShaderMaterial({
        vertexShader: FXAAShader.vertexShader,
        fragmentShader: FXAAShader.fragmentShader,
        uniforms: {
            tDiffuse: {
                value: edgeBuffer.texture
            },
            resolution: {
                value: new THREE.Vector2(1 / width, 1 / height)
            }
        },
        transparent: true,
        depthTest: false
    });

    object = obj

}

const onAfterRender = (renderer, scene, camera)=> {
    if (!object || !object.parent) {
        // TODO: this.object.parent为null时表示该物体被移除
        return;
    }

    let renderScene = scene;
    let renderCamera = camera;

    let selected = object;

    // 记录原始状态
    let oldOverrideMaterial = renderScene.overrideMaterial;
    let oldBackground = renderScene.background;

    let oldAutoClear = renderer.autoClear;
    let oldClearColor = new THREE.Color();

    renderer.getClearColor(oldClearColor);
    let oldClearAlpha = renderer.getClearAlpha();
    let oldRenderTarget = renderer.getRenderTarget();

    // 绘制蒙版
    hideObjects.length = 0;
    hideNonSelectedObjects(renderScene, selected, renderScene);

    renderScene.overrideMaterial = maskMaterial;
    renderScene.background = null;

    renderer.autoClear = false;
    renderer.setRenderTarget(maskBuffer);
    renderer.setClearColor(0xffffff);
    renderer.setClearAlpha(1);
    renderer.clear();

    renderer.render(renderScene, renderCamera);

    showNonSelectedObjects(renderScene, selected);
    hideObjects.length = 0;

    // 绘制边框
    quad.material = edgeMaterial;

    renderScene.overrideMaterial = null;

    renderer.setRenderTarget(edgeBuffer);
    renderer.clear();
    renderer.render(scene, camera);

    // 与原场景叠加
    quad.material = copyMaterial;

    renderer.setRenderTarget(null);
    renderer.render(scene, camera);

    // 还原原始状态
    renderScene.overrideMaterial = oldOverrideMaterial;
    renderScene.background = oldBackground;

    renderer.autoClear = oldAutoClear;
    renderer.setClearColor(oldClearColor);
    renderer.setClearAlpha(oldClearAlpha);
    renderer.setRenderTarget(oldRenderTarget);
}

const hideNonSelectedObjects = (obj, selected, root)=> {
    if (obj === selected) {
        let current = obj.parent;
        while (current && current !== root) {
            let index = hideObjects.indexOf(current);
            hideObjects.splice(index, 1);
            current.visible = current.userData.oldVisible;
            delete current.userData.oldVisible;
            current = current.parent;
        }
        return;
    }

    if (obj !== root) {
        obj.userData.oldVisible = obj.visible;
        obj.visible = false;
        hideObjects.push(obj);
    }

    for (let child of obj.children) {
        if (child instanceof THREE.Light) {
            continue;
        }
        hideNonSelectedObjects(child, selected, root);
    }
}

const showNonSelectedObjects = ()=> {
    hideObjects.forEach(n => {
        n.visible = n.userData.oldVisible;
        delete n.userData.oldVisible;
    });
}

const onStorageChanged = (name, value)=> {
    if (!edgeMaterial) {
        return;
    }
    if (name === 'selectedColor') {
        edgeMaterial.uniforms.color.value.set(value);
    } else if (name === 'selectedThickness') {
        edgeMaterial.uniforms.thickness.value = value;
    }
}

let raycaster = new THREE.Raycaster();
const mousePoint = reactive({x:0,y:0,z:0});
let originalMaterial = null;
let selectedObjects = [];
let mouse = new THREE.Vector2();
let offsetX = ref(0)
let offsetY = ref(0)
// 在画布内
let isIn = false
let gpuPick = {}

function pick(){
    //使用相机和鼠标位置更新选取光线  通过鼠标点的位置和当前相机的矩阵计算出raycaster
    raycaster.setFromCamera(mouse, oilMeshViewApp1.camera);
    //计算与选取光线相交的物体 获取raycaster直线和所有模型相交的数组集合
    let intersects = raycaster.intersectObjects(oilMeshViewApp1.scene.children, true);

    if (intersects.length > 0) { 
        let selected = intersects[0];//取第一个物体
        mousePoint.x = selected.point.x; 
        mousePoint.y = selected.point.y; 
        mousePoint.z = selected.point.z; 
        //console.log("x坐标:"+selected.point.x);
        //console.log("y坐标:"+selected.point.y);
        //console.log("z坐标:"+selected.point.z);
    }

    //采用包围盒过滤，计算投射光线与每个三角面元是否相交实现的
    if (intersects && intersects.length === 0 ) {

        if(selectedObjects.length){
            //递归搜索场景图 let object = scene.getObjectByName( "objectName", true );
            //通过ID进行搜索 let object = scene.getObjectById( 1, true );
            // 通过 name 来查找指定对象
            let meshTemp = oilMeshViewApp1.scene.getObjectByName(selectedObjects[0].name, true)
            meshTemp.material = originalMaterial
            selectedObjects = []
            originalMaterial = null
        }

        let body = document.querySelector('body')
        body.style.cursor = 'default'

        renderDiv([{name:""}])

        return false
    } else if(intersects && intersects.length > 0 && !isMeshType(intersects[0].object)){

        if(selectedObjects.length){
            // 通过 name 来查找指定对象
            let meshTemp = oilMeshViewApp1.scene.getObjectByName(selectedObjects[0].name)
            meshTemp.material = originalMaterial
        }

        selectedObjects = [];
        selectedObjects.push(intersects[0].object)
        originalMaterial = intersects[0].object.material

        //intersects[0].object.material.color = new THREE.Color('#123456')
        //轮廓渲染： 通过使用线框网格并在场景中放置适当的灯光，可以创建引人注目的轮廓渲染效果。
        //闪烁效果： 使用透明度和线框网格的组合，可以创建闪烁或闪烁的效果。
        //分段渲染： 通过将不同部分的网格渲染成不同的线宽或颜色，可以实现分段渲染效果。
        //使用压缩纹理、减少场景中的多边形数量、使用LOD（分级细节）技术和禁用不必要的灯光来优化Three.js的性能。
        //设置纹理贴图、修改颜色、透明度和网格线框
        //this.selectedObjects.material.color.set(0x00ff00)

        renderDiv(selectedObjects)

        let body = document.querySelector('body')
        body.style.cursor = 'pointer'

    } else {
        //console.log(intersects[0].object)
        let body = document.querySelector('body')
        body.style.cursor = 'pointer'

        renderDiv([{name:""}])

        if(intersects[0].object instanceof THREE.Mesh){

            oilMeshViewApp1.composerEffect = outlineObj([intersects[0].object], oilMeshViewApp1.renderer, oilMeshViewApp1.scene, oilMeshViewApp1.camera)

            //onObjectSelected([intersects[0].object][0],oilMeshViewApp1.renderer,oilMeshViewApp1.scene,oilMeshViewApp1.camera)
            //onAfterRender(oilMeshViewApp1.renderer, oilMeshViewApp1.scene, oilMeshViewApp1.camera)

            renderLabelDiv([intersects[0].object][0])

            if([intersects[0].object][0].parent && mousePoint){
                const { x,y,z } = mousePoint
                const boundingBox = new THREE.Box3().setFromObject([intersects[0].object][0]);
                const size = boundingBox.getSize(new THREE.Vector3());
                const center = boundingBox.getCenter(new THREE.Vector3());
                //initTween( x, center.y+20*size.y, z-2*size.z )
                //onChangeModelView(1);
            }

        } else {
          renderTarget(oilMeshViewApp1.renderer, oilMeshViewApp1.scene, oilMeshViewApp1.camera)
        }
        
    }


}

const doubleClick = (event) => {
    oilMeshViewApp1.composerEffect = null;
    document.querySelector("#label").style.display = "none"
    
    if(glassMaterial){
        //glassMaterial.color = new THREE.Color(parseInt(colorList[0]));
    }
}

function onMouseMove1(event){
    event.preventDefault()
    // event.stopPropagation()

    // event.preventdefault()方法是防止浏览器默认行为的最常用的方法之一，常用于表单提交、链接跳转等操作。
    // 同时，事件冒泡是指事件传递到父元素的过程，可以使用e.stopPropagation()方法阻止传播。
    // 在实际应用中，我们需要结合业务需求，谨慎使用这两个方法，达到更好的用户体验。

    if (event.target !== oilMeshViewApp1.renderer.domElement) { // 鼠标不在画布上
          isIn = false;
          gpuPick = {
              object: null,
              point: null,
              distance: 0
          };
          return;
      }
      isIn = true;
      offsetX = event.offsetX
      offsetY = event.offsetY

      //计算鼠标所在位置的设备坐标
      //三个坐标分量都是-1到1 通过鼠标点击的位置计算出raycaster所需要的点的位置，以屏幕中心为原点，值的范围为-1到1.
      mouse.x = event.clientX / window.innerWidth * 2 - 1;
      mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

      let vector = new THREE.Vector3();//三维坐标对象
        vector.set(
                ( event.clientX / window.innerWidth ) * 2 - 1,
                - ( event.clientY / window.innerHeight ) * 2 + 1,
                0.5 );
        vector.unproject( oilMeshViewApp1.camera );
      //raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

}

const infoTimeFu = ()=>{
    //if(infoTIME.value<=720){
        //infoTIME.value = infoTIME.value + 30
    //}else{
        //infoTIME.value = 0
    //}
}

onMounted(() => {
  addLoading();
  dom = document.querySelector("#webgl-app1");
  canvas = createCanvas();
  dom.appendChild(canvas);
  oilMeshViewApp1 = new OilApp1(canvas);

  renderer = oilMeshViewApp1.renderer
  oilMeshViewApp1.renderer.clippingPlanes = planeArr.value;
  scene  = oilMeshViewApp1.scene
  camera = oilMeshViewApp1.camera

  addOilMesh(url)

  createBatchMesh();
  let wellTemp = createMesh(0,850,0);
  wellTemp.name = "wellTemp";
  scene.add(wellTemp);

  addBox(0,1550,0);
  addSphere(0,1550,0);

  scene.add(modelItems)
  
  // 启动ThreeApp实例
  oilMeshViewApp1.render();
  //removeLoading();
})

onUnmounted(()=>{
  // 清理ThreeApp实例
  OilApp1.getInstance().clear();
  removeLoading();
})

</script>
<template>
    <div class="card">
        <div id="totalInfo">
            <p style="width: 100%;
                color: white;
                margin: 0 0 5px 0;
                font-size: 18px;
                text-align: center;">油井状态卡</p>
            <p style="margin: 0 0 5px 0;">
                <span style="color:#02851d">在线：{{wellInfo.reduce((sum, e) => sum + Number(e.cpr!="SHUT"?1:0 || 0), 0)}}&nbsp &nbsp</span>
                <span style="color:#c1c1c1">离线：{{wellInfo.reduce((sum, e) => sum + Number(e.cpr=="SHUT"?1:0 || 0), 0)}}</span>
            </p>
            <p style="margin: 0 0 5px 0;">
                <span style="color:#02851d">油藏模型</span><br/>
                <span style="color:#02851d">已显{{selectedModel.length||0}}层&nbsp &nbsp</span>
                <span style="color:#02851d">总计{{modelList.length||0}}层</span>
            </p>
        </div>

        <div id="modelInfo"></div>

        <div id="label">
            <p>网格名称: <span>{{ objectMesh && objectMesh.name}}</span></p>
            <p>大地坐标: <span>XCOORD0: {{ coord && coord.XCOORD0}} YCOORD0: {{ coord.YCOORD0 }}</span></p>
            <p>三维坐标: <span>XCOORD: {{ mousePoint && (mousePoint.x).toFixed(1)}} </span>
            <span> DEPTH: {{ mousePoint && (mousePoint.y).toFixed(1)}} </span>
            <span> YCOORD: {{ mousePoint && (mousePoint.z).toFixed(1)}}</span></p>
        </div>

        <div class="dockopticy mobile-bottom-opticy">
            <ul class="contents mobile-contents" style="justify-content: center;">
                <li data-type="MainView" :class="selectedMenu==0?'subbackColor':'cad_none'" @click="clickFun(0)">
                    <img src="../assets/images/bottomNav/MainView.png" />
                    <div class="tips" i18n="model_homeView" >主视图</div>
                </li>
                <li data-type="SubTransparency" :class="selectedMenu==1?'subbackColor':'cad_none'"  @click="selectFun(1)">
                    <img src="../assets/images/bottomNav/SubTransparency.png" />
                    <div class="three-level-directory">
                        <ul class="three-contents">
                            <li data-type="front" @click="initTween(0,0,10000)">
                                <img src="../assets/images/bottomNav/FrontView.png">
                                <div class="three-tips" i18n="model_frontView">前视角</div>
                            </li>
                            <li data-type="back" @click="initTween(0,0,-10000)">
                                <img src="../assets/images/bottomNav/RearView.png">
                                <div class="three-tips" i18n="model_backView">后视角</div>
                            </li>
                            <li data-type="left"  @click="initTween(-10000,0,0)">
                                <img src="../assets/images/bottomNav/LeftView.png">
                                <div class="three-tips" i18n="model_leftView">左视角</div>
                            </li>
                            <li data-type="right"  @click="initTween(10000,0,0)">
                                <img src="../assets/images/bottomNav/RightView.png">
                                <div class="three-tips" i18n="model_rightView">右视角</div>
                            </li>
                            <li data-type="bottom" @click="initTween(0,-10000,0)">
                                <img src="../assets/images/bottomNav/BottomView.png">
                                <div class="three-tips" i18n="model_bottomView">底视角</div>
                            </li>
                            <li data-type="top" @click="initTween(0,10000,0)">
                                <img src="../assets/images/bottomNav/TopView.png">
                                <div class="three-tips" i18n="model_topView" >顶视角</div>
                            </li>
                        </ul>
                    </div>
                </li>

                <li data-type="ModelExplosion" :class="selectedMenu==3?'subbackColor':'cad_none'"  @click="clickFun(3)">
                    <img src="../assets/images/bottomNav/ModelExplosion.png">
                    <div class="tips" i18n="model_modelExplosion">模型爆炸</div>
                </li>

                <li data-type="SubSectioning"  :class="selectedMenu==2?'subbackColor':'cad_none'"  @click="clickFun(2)">
                    <img src="../assets/images/bottomNav/SubSectioning.png">
                    <div class="tips" i18n="model_subSectioning" >模型剖切</div>
                </li>

                <li data-type="ModelColorSettings" :class="selectedMenu==4?'subbackColor':'cad_none'"  @click="clickFun(4)">
                    <img src="../assets/images/bottomNav/ModelColorSettings.png">
                    <div class="tips" i18n="model_modelColor">模型配色</div>
                </li>

                <li data-type="ModelChange" :class="selectedMenu==5?'subbackColor':'cad_none'"  @click="clickFun(5)">
                    <img src="../assets/images/bottomNav/FloorLayering.png">
                    <div class="tips" i18n="model_modelChange">切换模型</div>
                </li>

                <li data-type="GridSetup" :class="selectedMenu==6?'subbackColor':'cad_none'"  @click="clickFun(6)">
                    <img src="../assets/images/bottomNav/GridSetup.png">
                    <div class="tips" i18n="model_gridSettings">切换网格</div>
                </li>

            </ul>
        </div>

        
        <div id="rightSlicingModelInterface"  v-if="modelSubSectioning">
            <div class="rightdiv" id="rightSlicingModel_div" style="display: block;">
                <div class="right-detection-list">
                    <div class="layer-title" i18n="model_dragCut">模型剖切</div>
                    <span class="layer-setwin" @click="closeModelCut()">
                        <img src="../assets/images/bottomNav/close-outline.svg" width="20px" height="20px"/></span>
                    <div class="right-detection-list-main layer-content" style="height:8rem;width:100%;">
                        <ul class="lanren sectioning-box" style="padding: 0px; display:block;margin: 6px;">
                            <li>
                                <span i18n="model_X_axis">X轴：</span>
                                <div class="paoqie_div" id="range_1">
                                    <input type="range" min="1" max="5000" value="5000" class="slider" v-model="planeArr[0].constant" v-on:input="inputFunc1()" id="xRange"/></div>
                                    <span id="xvalue">{{ planeArr[0].constant }}m</span>
                            </li>
                            <li>
                                <span i18n="model_Y_axis">Y轴：</span>
                                <div class="paoqie_div" id="range_2">
                                    <input type="range" min="1" max="2000" value="1500" class="slider" v-model="planeArr[1].constant" v-on:input="inputFunc2()" id="yRange"/></div>
                                    <span id="yvalue">{{ planeArr[1].constant }}m</span>
                            </li>
                            <li>
                                <span i18n="model_Z_axis">Z轴：</span>
                                <div class="paoqie_div" id="range_3">
                                    <input type="range" min="1" max="5000" value="5000" class="slider" v-model="planeArr[2].constant" v-on:input="inputFunc3()" id="zRange"/></div>
                                    <span id="zvalue">{{ planeArr[2].constant }}m</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>


        <div id="rightSlicingModelInterface1"  v-if="modelColorChange">
            <div class="rightdiv" id="rightSlicingModel_div1" style="display: block;">
                <div class="right-detection-list">
                    <div class="layer-title" i18n="model_dragCut">模型配色</div>
                    <span class="layer-setwin" @click="closeModelColorChange()">
                        <img src="../assets/images/bottomNav/close-outline.svg" width="20px" height="20px"/></span>
                    <div class="right-detection-list-main layer-content" style="height:13rem;width:100%;">
                        <div class="color-picker">
                            <div class="colorSlider">
                                <div class="slider-container">
                                    <label for="hueSlider">色相H(0-360):</label>
                                    <input class="slider" style="width: auto;" type="range" id="hueSlider" min="0" max="360" value="0">
                                </div>

                                <div class="slider-container">
                                    <label for="saturationSlider">饱和度S(%):</label>
                                    <input class="slider" style="width: auto;" type="range" id="saturationSlider" min="0" max="100" value="100">
                                </div>

                                <div class="slider-container">
                                    <label for="lightnessSlider">亮度L(%):</label>
                                    <input class="slider" style="width: auto;" type="range" id="lightnessSlider" min="0" max="100" value="100">
                                </div>

                                <div class="slider-container">
                                    <label for="opacitySlider">透明度(%):</label>
                                    <input type="range" id="opacitySlider" class="slider" style="width: auto" min="1" max="100" value="90">
                                </div>

                                <div>
                                    <button :class="optNum===10?'changeModelColor active':'changeModelColor'"  @click="changeModelOptions()">depth</button>
                                    <button :class="optNum===0?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(0,6,5,2000,3000)">permx</button>
                                    <button :class="optNum===1?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(1,4,5,3000,4000)">permz</button>
                                    <button :class="optNum===2?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(2,5,3,4000,5000)">poro</button>
                                </div>

                                <div>
                                    <button  :class="optNum===3?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(3,4,3,6000,6000)">poil</button>
                                    <button  :class="optNum===4?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(4,2,3,8000,7000)">soil</button>
                                    <button  :class="optNum===5?'changeModelColor active':'changeModelColor'"  @click="changeModelColor(5,3,1,10000,8000)">swat</button>
                                </div>

                            </div>
                            
                            <div class="color-preview" id="colorPreview"></div>

                        </div>
                    
                    </div>
                </div>
            </div>
        </div>


        <div id="leftSlicingModelInterface"  v-if="modelChange">
            <div class="leftdiv" id="leftSlicingModel_div" style="display: block;">
                <div class="left-detection-list">
                    <div class="layer-title" i18n="model_dragChange">切换模型</div>
                    <span class="layer-setwin" @click="closeModelChange()">
                        <img src="../assets/images/bottomNav/close-outline.svg" width="20px" height="20px"/></span>
                    <div class="left-detection-list-main layer-content">
                        <ul class="leftlanren leftsectioning-box">
                            <li v-for="(item, index) in modelList" :key="'model'+index" :class="selectedModel.includes(index)?'subbackColor':'cad_none'">
                                <input type="checkbox" readonly disabled :id="index"  name="modelIndex" :value="index" :checked="selectedModel.includes(index)" />

                                <span i18n="model">{{index}}</span>
                                <button class="selectModel" @click="modelChangeFun(index)" :disabled="btnDisabled">
                                    <p>{{item.slice(37)}}</p>
                                </button>

                                <button v-if="selectedModel.includes(index)" class="delete" @click="deleteModel(index)"  :title="'点击删除'+index+'层油藏模型'">X</button>

                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>


        <div class="color-palette">
            <div class="color-card" v-for="(item,index) in colorsPaletteArrObj" :key= "'palette'+index" :style="`background:${item.color}`">{{item.name}}</div>
        </div>

        <div id="tips">
            <div
                class="topTips"
                :style="`background:${item.cpr=='SHUT'?'#c1c1c199':'#00FF0099'};display:${item.showStatus?'block':'none'};transform: ${item.showStatus?'scale(1)':'scale(0)'};border: 2px solid ${item.cpr=='SHUT'?'#c9c9c9':'#00FF00'}`"
                v-for="(item, index) in wellInfo" :key="index"
            >
                <div
                class="arrows"
                :style="`border-bottom-color: ${item.cpr=='SHUT'?'#c9c9c9':'#00FF00'}`"
                ></div>
                <p style="display: flex;justify-content: space-between;font-size: 20px;align-items: center;margin: 10px 0 0 0;">
                <span>油井状态：{{item.cpr=="SHUT"?"离线":"在线"}}</span>
                <router-link style="fill: #fff;" :to="{ path: '#', query: { id: item.id }}"></router-link>
                </p>
                <p style="display: flex;justify-content: space-between;"><span>井号：{{item.id}}</span></p>
                <p style="display: flex;justify-content: space-between;"><span>井名：{{item.name}}</span></p>
                <p style="display: flex;justify-content: space-between;"><span>井节点数目：{{item.num}}</span></p>
                <p style="display: flex;justify-content: space-between;"><span>当前生产制度：{{item.cpr}}</span></p>
                <p style="display: flex;justify-content: space-between;">
                    <span>数据时间：<!--{{ infoTIME || 30 }}</span>-->
                    <!--<select name="infoTime" id="infoTime">
                        <option v-for="(i) in 25" :value="((i-1)*30).toString()" :disabled="i==1?true:false" :selected="i==2?true:false">{{((i-1)*30)}}</option>
                    </select>-->
                    <input class="slider" style="width: auto;"  type="range" min="0" max="720" value="30" step="30" v-model="infoTIME" v-on:input="infoTimeFu()" id="infoTIME"/>
                    <span id="infoTIMESpan">{{ infoTIME }}</span>
                </span>
                </p>
                <p style="display: flex;justify-content: space-between;"><span>动态数据：</span></p>
                <ul style="height: 100px;overflow:auto;">
                    <li v-for="(i,k) in item.data[0].motion" :key="'motion'+k" style="text-align: left;">
                        {{i.key}}：{{(getWellTimePropValue(infoTIME.toString(),item.id,i.key)!=null)?getWellTimePropValue(infoTIME.toString(),item.id,i.key)[0]:0}} (单位:{{i.unit}}) </li>
                </ul>
            </div>
        </div>

        <div id="webgl-app1" @mousemove="onMouseMove1($event)" @click="pick()"  @dblclick="doubleClick()"></div>
    </div>
</template>
<style scoped>
#webgl-app1{
  flex: 1 1 0px;
  outline: none;
  background-image: linear-gradient(rgba(0, 0, 1,0.4), rgba(119, 119, 237,0.8));
}

.card{
    position: relative;
}

#totalInfo{
    width: 250px;
    box-shadow: 0 0 10px #2c58a6;
    /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */
    filter: drop-shadow(10px 10px 20px rgba(0, 255, 0, 0.5));
    box-sizing: border-box;
    border: 1px solid #ebeef5;
    background: #04323066;
    padding: 10px;
    border-radius: 5px;
    position: absolute;
    display:flex;
    justify-content: space-around;
    align-items: center;
    flex-wrap: wrap;
    top: 80px;
    left: 10px;
    transition: 0.6s;
}

#tips{
    position: absolute;
    transition: 0.0s;
}

.topTips {
  width: 320px;
  color: #000b3d;
  border-radius: 5px;
  padding: 10px;
  position: relative;
  transition: 0.6s ease 0.6s;
}

.topTips > .arrows {
    width: 0;
    height: 0;
    border: 10px solid transparent;
    border-bottom-width: 12px;
    position: absolute;
    top: -22px;
    left: 0;
    right: 0;
    margin: auto;
}

#totalInfo {
    animation-name: beat;
    animation-duration: 2s;
    animation-timing-function: ease;
    animation-iteration-count: infinite;
}

@keyframes beat{
    0% { 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #ebeef5;
      -webkit-box-shadow: 0 0 10px #2c58a6;
      box-shadow: 0 0 10px #2c58a6;
    }
    20%{ 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #00fff5;
      -webkit-box-shadow: 0 0 9px #00fff5;
      box-shadow: 0 0 9px #00fff5;
    }
    40%{ 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #00fff4;
      -webkit-box-shadow: 0 0 8px #00fff4;
      box-shadow: 0 0 8px #00fff4;
    }
    60%{ 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #00fff3;
      -webkit-box-shadow: 0 0 7px #00fff3;
      box-shadow: 0 0 7px #00fff3;
    }
    80%{ 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #00fff2;
      -webkit-box-shadow: 0 0 6px #00fff2;
      box-shadow: 0 0 6px #00fff2;
    }
    100%{ 
      transform: translate(0em, 0em) scale(1);
      border: 1px solid #00fff1;
      -webkit-box-shadow: 0 0 5px #00fff1;
      box-shadow: 0 0 5px #00fff1;
    }
}

.tag {
    padding: 0px 10px;
    border: #00ffff solid 1px;
    height: 40px;
    border-radius: 5px;
    color: white;
    width: 65px;
    font-size: 12px;
    backface-visibility: hidden;
}

#label{
    position: absolute;
    border: 1px solid #9E9E9E;
    border-radius: 5px;
    background: #3f3e3c;
    padding: 0 10px;
    left: 10px;
    bottom: 20px;
    display: none;
}

#label::before{
   content: "";
   position: absolute;
   top: 0;
   left: 0;
   width: 0;
   height: 0;
   border-style: solid;
   border-width: 0 15px 15px 0; /* 调整这些值来改变三角形的大小 */
   border-color: transparent transparent orange transparent; /* 调整颜色来改变三角形的颜色 */
   border-radius: 0 0 0 5px;
   transform: rotate(90deg);
}

#label>p{
    color: #f0f0f0;
    font-size: 12px;
    font-weight: 100;
    text-align: left;
}

.dockopticy {
    /*height: 3.6rem;*/
    bottom: 1rem;
    border-radius: 0.5rem;
    background-color: rgba(0, 0, 0, .8);
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    border: 0.1rem solid #706f6d;
}

.contents {
    width: 100%;
    font-size: 1.2rem;
    padding: 0;
    /*height: 3.6rem;
    line-height: 3rem;*/
    margin: 0 auto;
    display: flex;
    flex-wrap: nowrap;
    transition: 0.01s;
}

ul li {
    list-style: none;
}

.contents li:hover{
    background-color: #3f3e3c;
    border-radius: 0.5rem;
    transform: scale(1.1);
}

.contents li:hover .three-level-directory{
    display: block;
}

.contents li:hover .tips{
    display: block;
}

.dockopticy li {
    font-size: 1.2rem;
    padding: 0.3rem 1.2rem;
    position: relative;
}

.contents li {
    cursor: pointer;
}
.subbackColor {
    background-color: #3f3e3caa;
    border-radius: 0.5rem;
}
.cad_none{
    background: transparent;
}
.dockopticy img {
    width: 2.2rem;
    height: 2.2rem;
    border: none;
}

li .tips {
    position: absolute;
    padding: 0.6rem 0.8rem;
    color: #fff;
    background-color: rgba(0, 0, 0, .8);
    top: -2.8rem;
    left: 0.4rem;
    line-height: 1.3rem;
    border-radius: 0.3rem;
    display: none;
    white-space: nowrap;
}


.three-level-directory ul {
    flex-direction: column;
    background-color: rgba(0, 0, 0, .8);
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    border: 0.1rem solid #706f6d;
    border-bottom: none;
    box-sizing: border-box;
}

.three-contents {
    width: 100%;
    font-size: 1.2rem;
    padding: 0;
    /*line-height: 3rem;*/
    margin: 0 auto;
    display: flex;
    flex-wrap: nowrap;
}

.three-level-directory {
    position: absolute;
    bottom: 100%;
    left: 0;
    display: none;
}
.three-level-directory ul {
    flex-direction: column;
    background-color: rgba(0, 0, 0, .8);
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    border: 0.1rem solid #706f6d;
    border-bottom: none;
    box-sizing: border-box;
}
.three-tips {
    position: absolute;
    padding: 0.6rem 0.8rem;
    color: #fff;
    background-color: rgba(0, 0, 0, .8);
    bottom: 0;
    left: 50px;
    line-height: 1.3rem;
    border-radius: 0.3rem;
    display: none;
    white-space: nowrap;
}
.three-contents li:hover .three-tips{
    display: block;
}

.right-detection-list {
    position: absolute;
    top: 8%;
    right: 1%;
    width: 26rem;
}

.left-detection-list {
    position: absolute;
    top: 170px;
    left: 10px;
    width: 250px;
    border-radius: 10px;
}

.layer-title {
    text-overflow: ellipsis;
    white-space: nowrap;
}
.layer-title {
    background-color: #3f3e3c ;
    color: #fff ;
    opacity: 0.8;
    border-bottom: 0.1rem solid #666;
    padding: 10px;
    height: 2rem ;
    font-size: 1rem ;
    border-radius: 0.2rem 0.2rem 0 0 ;
    line-height: 2rem ;
}
.layer-setwin {
    position: absolute;
    right: 15px;
    top: 17px;
    font-size: 0;
    line-height: initial;
}

.layer-setwin {
    top: 13px ;
}

.layer-setwin:hover{
    cursor: pointer;
}

.layer-setwin .layer-close {
    background-position: 1px -40px;
    cursor: pointer;
}


.layer-content {
    position: relative;
}

.layer-content {
    background-color: rgba(45, 33, 33, 0.75);
    color: #fff;
}
.right-detection-list-main {
    width: 26rem;
    color: #fff;
    border-top: none;
    position: absolute;
    float: left;
}

.left-detection-list-main {
    color: #fff;
    border-top: none;
    position: absolute;
    float: left;
    height:auto;
    width:100%;
    padding: 5px 0;
}

.lanren li {
    display: flex;
    align-items: center;
}

.lanren li {
    font-size: 16px;
    line-height: 38px;
    position: relative;
    height: 38px;
    list-style: none;
}

.leftlanren li {
    display: flex;
    align-items: center;
}

.leftlanren li {
    font-size: 16px;
    line-height: 38px;
    position: relative;
    height: 38px;
    list-style: none;
}

.leftlanren li p {
    overflow: hidden; /* 隐藏超出元素框的内容 */
    text-overflow: ellipsis; /* 使用省略号表示被修剪的文本 */
    display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */
    -webkit-box-orient: vertical; /* 设置盒子的垂直布局 */
    -webkit-line-clamp: 1; /* 限制在一个块元素显示的文本的行数 */
    margin: 1px;
    padding: 5px;
}

.leftlanren li p:hover{
    background-color: #3f3e3c;
    border-radius: 0.5rem;
    transform: scale(1.05);
    /*cursor:pointer;*/
}

.sectioning-box li > span {
    width: 20%;
    text-align: center;
}

.paoqie_div {
    width: 74%;
}

.leftsectioning-box{
    height: 590px;
    overflow: auto;
    padding: 0px; 
    display:block;
    margin: 6px;
}

.leftsectioning-box li > span {
    width: 20%;
    text-align: center;
}

.selectModel {
    width: 150px;
    background: transparent;
    padding: 0;
    color: white;
    text-align: left
}

.changeModelColor {
        line-height: 18px;
        padding: 2px;
        margin: 3px 5px 0 0;
        background: #002030;
        color: #10c2c088;
        border: 1px solid #009688;
        border-radius: 5px;
        cursor: pointer;
        white-space: nowrap;
        word-break: keep-all;
        overflow: hidden;
        text-overflow: ellipsis;
        text-align: center;
        transition: .6s;
    }

    .changeModelColor:hover {
        color: #10c2c0;
    }

    .active{
        color: #09f3ef;
        background: linear-gradient(to top, #002030, #009688);
    }

.layui-slider {
    height: 4px;
    background: #eee;
    border-radius: 3px;
    position: relative;
    cursor: pointer;
}

.layui-slider-tips {
    position: absolute;
    top: -42px;
    z-index: 66666666;
    white-space: nowrap;
    display: none;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
    color: #FFF;
    background: #000;
    border-radius: 3px;
    height: 25px;
    line-height: 25px;
    padding: 0 10px;
}

.layui-slider-bar {
    border-radius: 3px;
    position: absolute;
    height: 100%;
}

.layui-slider-bar {
    background: #2f86da ;
}

.paoqie_div .layui-slider-wrap {
    line-height: 36px;
}

.layui-slider-wrap {
    width: 36px;
    height: 36px;
    position: absolute;
    top: -16px;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
    z-index: 10;
    text-align: center;
}

.layui-slider-wrap-btn {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #FFF;
    display: inline-block;
    vertical-align: middle;
    cursor: pointer;
    transition: .3s;
}

.layui-slider-wrap-btn {
    border: 2px solid #2f86da ;
}

.layui-slider-wrap:after {
    content: "";
    height: 100%;
    display: inline-block;
    vertical-align: middle;
}

/* The slider itself */
.slider {
    -moz-appearance: none;
    -o-appearance: none;
    -ms-appearance: none;
    -webkit-appearance: none;  /* Override default CSS styles */
    appearance: none;
    width: 100%; /* Full-width */
    height: 15px; /* Specified height */
    background: #d3d3d3; /* Grey background */
    outline: none; /* Remove outline */
    opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */
    -webkit-transition: .2s; /* 0.2 seconds transition on hover */
    transition: opacity .2s;
    border-radius: 5px;
}

/* Mouse-over effects */
.slider:hover {
    opacity: 1; /* Fully shown on mouse-over */
}

/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */
.slider::-webkit-slider-thumb {
    -moz-appearance: none;
    -o-appearance: none;
    -ms-appearance: none;
    -webkit-appearance: none; /* Override default look */
    appearance: none;
    width: 25px; /* Set a specific slider handle width */
    height: 25px; /* Slider handle height */
    background: #04AA6D; /* Green background */
    cursor: pointer; /* Cursor on hover */
    border-radius: 50%;
}

.slider::-moz-range-thumb {
    width: 25px; /* Set a specific slider handle width */
    height: 25px; /* Slider handle height */
    background: #04AA6D; /* Green background */
    cursor: pointer; /* Cursor on hover */
    border-radius: 50%;
}

/*定义滚动条高宽及背景
高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar
{
    width:16px;
    height:16px;
    background-color:#F5F5F511;
}
/*定义滚动条轨道
内阴影+圆角*/
::-webkit-scrollbar-track
{
    -webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.3);
    border-radius:10px;
    background-color:#F5F5F533;
}
/*定义滑块
内阴影+圆角*/
::-webkit-scrollbar-thumb
{
    border-radius:10px;
    -webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);
    background-color:#123456;
}

/*滚动条宽度*/
div::-webkit-scrollbar {
    width: 6px;
}
/*滚动条轨道*/
div::-webkit-scrollbar-track {
    background: rgb(239, 239, 239);
    border-radius: 2px;
}
/*小滑块*/
div::-webkit-scrollbar-thumb {
    background: #40a0ff49;
    border-radius: 10px;
}
div::-webkit-scrollbar-thumb:hover {
    background: #40a0ff;
}


.color-palette {
    display: flex;
    flex-wrap: wrap;
    gap: 0px;
    padding: 0px;
    position: absolute;
    right: 10px;
    width: 45px;
    top: 60%;
}
.color-card {
    width: 40px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: black;
    font-family: Arial, sans-serif;
    font-size: 12px;
    border: 1px solid white;
}


.color-picker {
    width: auto;
    margin: 0 auto;
    position: absolute;
    right: 10px;
    left: 20px;
    display: flex;
    margin: 10px 0;
}

.color-preview {
    width: 100%;
    height: 75px;
    border: 0px solid #000;
    margin-bottom: 10px;
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0;
    margin: 10px;
}
.slider-container {
    margin-bottom: 10px;
    text-align: left;
    padding: 0 0 0 10px;
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0;
    display: flex;
    justify-content: right;
}
.slider-container label{
    width:110px;
    text-align: right;
}
.delete{
    width: 20px;
    height: 20px;
    line-height: 20px;
    font-size: 12px;
    padding: 0;
    background: #607D8B;
    color: white;
}
</style>